セキュリティ

Fuel はセキュリティをとても真剣に考え、その結果、あなたの Web アプリケーションの安全を確保するための次の対策を実装しました。

デフォルトでは Fuel は入力時に POST や GET 変数をフィルタせず、出力時にすべてをエンコードします。 Fuel はまた URI セグメントを使ったときに予期せぬことが起こらないように URI もエンコードし、データベース操作時に全てエスケープ処理をします。

このページでは Fuel が提供する一般的なセキュリティ対策を説明し、Security クラスはクラスのセクションにドキュメントされています。Fuel の Security クラスの設定の詳細についてはそちらのページで見つけることができます。

出力エンコーディング

デフォルトでは、Fuel は入力フィルタリングより出力エンコーディングを好みます。その理由は2つの要素からなります。 あなたのデータがどこから来たものであろうと、そしてそれがフィルタされていようがいまいが、出力エンコーディングはそのデータを クライアントに送信する際に無害にします。これは、すべての入力は生のまま、変更のないかたちで保存され、何が起ころうと、 あなたはいつでも元データにアクセスできるとことも意味します。

これは、あなたが変更のないかたちでのデータを必要とするときに、困ったことにならないことも意味します。ひとつの一般的な例は、 エンドユーザがコンテンツを編集するために多くのアプリケーションで利用されている TinyMCE や ckeditor のような HTML エディタで生成されるデータです。 そのようなケースでは、あなたは忍び込むかもしれない予期せぬ嫌なことを取り除くために入力された変数に XSS フィルタリングを実行することを望むかもしれません。これはあなたが出力時にエンコードすることも 望まない典型的な例です。

出力エンコーディングは文字列にだけ起こるため、あなたがビューにオブジェクトを渡したいときは注意しなければいけません。 あなたのオブジェクトが __toString() メソッドを持っているか、その場合はエンコーディングが起こります、あなたのオブジェクトをセキュリティ設定のクラスのホワイトリストに追加するか(名前空間を忘れずに!)、 オブジェクトを $encode を false にセットして ビューに渡すかを確認してください。 あなたは、auto_encode メソッドを使い、ビューごとに、自動出力エンコーディングを 一時的に無効にすることもできます。

これがビューにどのように実装されているかは、ビューのセキュリティのセクションを参照してください。

CSRF 保護

ワンクリック攻撃またはセッションライディングとも言われ、CSRF と略されるクロスサイト・リクエストフォージェリは、Web サイトが信頼するユーザから送信される 承認されていない命令による悪意のある攻撃の一種です。クロスサイトスクリプティング (XSS) とは異なり、 ユーザが持つ特定のサイトでの信頼を悪用し、CSRF はユーザのブラウザの中にサイトが持つ信頼を悪用します。 攻撃は、ユーザが認証されていることが知られる (あるいは想定される) サイトにアクセスするリンクやスクリプトを含むページにより なされます。

例えば、あるユーザ、ボブは、他のユーザ、マロリーがメッセージを投稿したチャットフォーラムをブラウズするとします。 マロリーは、ボブの銀行の Web サイトでのアクションを参照する HTML イメージ要素を巧妙に作り上げたとします(画像ファイルではなく)。 もし、ボブの銀行が認証情報をクッキーに保存し、そのクッキーの期限が切れていなければ、ボブのブラウザが画像をロードしようとすると、 預金の引き出しフォームへクッキーとともに投稿してしまい、ボブが承認せずに正当な取引として処理されてしまいます。 情報源: wikipedia

Fuel は、フォームにセキュリティトークンを含ませることで、この種の攻撃からあなたのフォームを保護するツールを提供します。 フォームの投稿時にトークンは検証され、検証済みの場合、フォームはフォークをリクエストしたクライアントから投稿されたことが確認されます。

CSRF 保護はアプリケーションの config/config.php ファイルの security セクションで設定できます。

CSRF 保護を有効にするには、まず、フォームにトークンを追加します:

// プレーンな HTML で
<input type="hidden" name="<?php echo \Config::get('security.csrf_token_key');?>" value="<?php echo \Security::fetch_token();?>" />

// Form クラスを使って
echo \Form::csrf();

// form インスタンスを使い、フォームのフィールドセットに検証ルールを追加して
$form = \Form::forge();
$form->add_csrf();

フォームをリクエストしてクライアントによって投稿されたかどうかを手動でチェックするには:

// フォームが投稿されたかどうかチェック
if ($_POST)
{
	// CSRF トークンが正しいかチェック
	if ( ! \Security::check_token())
	{
		// CSRF 攻撃または CSRF トークンの期限切れ
	}
	else
	{
		// トークンは正しいので、フォームの入力を処理する
	}
}

XSS フィルタリング

Fuel は、とても高速で高度に設定可能な HTMLawed ライブラリを使い、XSS フィルタリングを提供します。 ライブラリは、デフォルトではセーフおよびバランスモードで実行されます。

セーフとは、HTML 標準仕様に準拠した文法的に正しいかも知れない HTML コードに基づく、スクリプティング攻撃 (XSS のような) の脆弱性を減少させる 制限された HTML にします。 script や object のような要素、そして onmouseover や style なのど属性が入力テキストで許可されるとき、入力者は悪意のある HTML コードを挿入することができます。

バランスモードでは、HTMLawed は入力をチェックし、適切に閉じられたタグと文法的に正しい要素の内容に修正します (すなわち、ネストされた要素は文法的に正しい必要があり、プレーンテキストは許可された要素の内容にのみ存在できます)。[訳注: 現在、バランスモードはオフに設定されています]

パフォーマンスの理由から、xss_clean メソッドは包括的な入力フィルタとしてではなく、 個別の入力値に使うことをお薦めします。

入力フィルタリング

デフォルトでは有効になっていませんが、すべてのページリクエストで Fuel がすべての入力 ($_GET, $_POST and $_COOKIE) をフィルタするように設定できます。 そうするには、アプリケーションの config/config.php ファイルでフィルタに使用する関数やメソッドを設定します。

/**
 * Security settings
 */
'security' => array(
    'input_filter' => array(),
)

引数として1つの値を受け入れるPHPで実行可能なものはすべてフィルタリングのために使用できます。 PHP の 'htmlentities' のような関数、'\\Security::xss_clean' のような静的クラスメソッド、 あるいは array($object, 'method') のようなオブジェクトメソッドも使用できます。 もし、オブジェクトメソッドを使う場合は、Fuel が初期化される前にそのオブジェクトが利用できることを確認してください。入力フィルタはリクエストプロセスのとても初期段階で実行されます。

SQL インジェクション

SQL インジェクションはアプリケーションのデータベースレイヤー(SQLクエリーのような)で起こるセキュリティ脆弱性を悪用するコード挿入テクニックです。 脆弱性はユーザ入力の、SQL 文に埋め込まれる文字列リテラルのエスケープ文字が正しくフィルタされていないか、ユーザ入力が強く型付けされておらず、 それゆえ予期せず実行される場合に存在します。 これは、もっと一般的な脆弱性の分類としては、1つのプログラミングまたはスクリプティング言語が別の言語に含まれる場合に起こるものの一例です。 SQLインジェクション攻撃は、SQL 挿入攻撃とも言われます。
この形式の SQL インジェクションは、ユーザ入力のエスケープ文字がフィルタされておらず、SQL文に渡される場合に起こります。 これは結果として、アプリケーションのエンドユーザによるデータベースで実行される SQL 文の潜在的な操作をもたらします。 情報源: wikipedia

Fuel は、Database クラスのメソッドの1つに渡されるすべての値をエスケープすることにより、SQLインジェクションから保護します。 これは Fuel の中心となるクエリビルダーのレベルで起こるため、クエリビルダーを使うすべてのコード、Fuel の ORM パッケージを含みます、は自動的にエスケープされます。