セキュリティ ======== クロスサイトスクリプティング (XSS) の防止 ------------------------------- クロスサイトスクリプティング (XSS としても良く知られます) は、ウェブアプリケーションが悪意のあるデータをユーザから回収した時に引き起こされます。 攻撃者はたびたび、JavaScript, VBScript, ActiveX, HTML あるいは Flash を脆弱なアプリケーションに注入して、他のアプリケーションユーザを欺瞞したり彼らからデータを収集したりします。 例えば、貧弱にデザインされたフォーラムのシステムは、ユーザが入力したフォーラムへの投稿を全くチェックする事なく表示するでしょう。 この場合、攻撃者が悪意のある JavaScript のコード断片を記事へ注入することが可能で、他のユーザ達がこの記事を読んだ時に、JavaScript が彼らのコンピュータの中で予期せぬ動きをすることが有り得ます。 XSS 攻撃に対する防御のもっとも重要な手段の一つは、表示する前にユーザからの入力をチェックする事です。 これを成し遂げるために、ユーザ入力に対して HTML エンコーディングを施すことも可能です。 しかしながら、HTML エンコーディングは全ての HTML タグを使えなくしてしまうため、これが望ましくない状況もあるでしょう。 Yii は [HTMLPurifier](http://htmlpurifier.org/) の成果を組み込んで、[HTMLPurifier](http://htmlpurifier.org/) をカプセル化した [CHtmlPurifier] という便利なコンポーネントを開発者に提供します。 このコンポーネントは、徹底的に検査された安全かつ寛容なホワイトリストを使って、全ての悪意のあるコードを除去することが出来るものです。また、フィルターされたコンテンツが標準に準拠していることを保証してくれるものです。 [CHtmlPurifier] コンポーネントは、[ウィジェット](/doc/guide/basics.view#sec-3) としても [フィルタ](/doc/guide/basics.controller#sec-5) としても使用可能です。 ビューの中でウィジェットとして使用した場合、[CHtmlPurifier] はボディーとして表示されたコンテンツから不純物を取り除いてくれます。 例えば、 ~~~ [php] beginWidget('CHtmlPurifier'); ?> ... ここにユーザが入力したコンテンツを表示する ... endWidget(); ?> ~~~ クロスサイトリクエストフォージェリ (CSRF) の防止 ------------------------------------- クロスサイトリクエストフォージェリ (CSRF) による攻撃は、悪意のあるウェブサイトが、ユーザのブラウザに対して、信頼済みのサイトへ望んでないアクションを行わせる事で引き起こされます。 例えば、悪意のあるウェブサイトがイメージタグを含んでいて、その `src` が、オンラインバンクのサイトの `http://bank.example/withdraw?transfer=10000&to=someone` になっているとします。 もしユーザが、オンラインバンキングへログインした状態のクッキーを持っていて、この悪意のあるコードを含んだサイトを訪れた場合、someone へ 10,000 ドルを送金 (transfer) するアクションが引き起こされるでしょう。 XSS は、特定のサイトに対してユーザが持っている信頼を悪用します。それとは反対に、CSRF は特定のユーザに対してサイトが持っている信頼を悪用します。 CSRF 攻撃を防ぐには、`GET` リクエストに対してはデータの取得のみを許可し、サーバのデータを変更する事は一切許すべきでない、というルールに従う事が重要です。 そして `POST` リクエストについては、サーバが認識出来る何らかのランダム値を `POST` リクエストに含めて、フォームの送信元と結果の返送先が同一である事を確認するようにするべきです。 Yii は `POST` ベースの攻撃に対する防御を助けるために、CSRF を防ぐスキーマを実装しています。 これは、ランダム値をクッキーに保存し、`POST` リクエストによって送信された値と比較する事で成り立っています。 初期状態では、CSRF に対する防御は無効になっています。 有効にするには、[アプリケーション初期構成](/doc/guide/basics.application#sec-2) の中で [CHttpRequest] コンポーネントを下記の様に設定して下さい。 ~~~ [php] return array( 'components'=>array( 'request'=>array( 'enableCsrfValidation'=>true, ), ), ); ~~~ そしてフォームを表示するには、HTML の form タグを直接書く代わりに、[CHtml::form] をコールします。 [CHtml::form] メソッドは必要なランダム値を hidden フィールドにして埋め込み、CSRF 検証のために送信させる事ができます。 クッキー攻撃の防止 ------------------------ セッション ID がクッキーに含まれている場合、クッキーを攻撃から守る事は、とてつもなく大切です。 もし誰かがセッション ID を手中に収めた場合、彼はセッションに関連する全ての情報を手に入れた事になります。 クッキーを攻撃から守るためのいくつかの対策があります。 * アプリケーションは SSL を使って安全なコミュニケーションチャンネルを作り、HTTPS 接続による認証クッキーのみを通す様にする事が出来ます。 攻撃者はこれによって送信されたクッキーの内容を解読することが出来なくなります。 * 全てのクッキーとセッションに対して、セッションを適切な有効期限内で打ち切る様にし、攻撃される可能性を減少させます。 * クロスサイトスクリプティング (XSS) を防ぎます。XSS は、任意のコードをユーザのブラウザで動作させ、クッキーを危険に晒します。 * クッキーのデータを検証し、改変を検出する様にします。 Yii はクッキーバリデーションスキーマを実装し、クッキーが改変される事を防ぎます。 具体的には、もしクッキーバリデーションが有効なら、クッキーの値に対して HMAC チェック行います。 クッキーバリデーションは初期状態では無効になっています。 有効にするには、[アプリケーション初期構成](/doc/guide/basics.application#sec-2) の中の [CHttpRequest] アプリケーションコンポーネントを下記の様に設定します。 ~~~ [php] return array( 'components'=>array( 'request'=>array( 'enableCookieValidation'=>true, ), ), ); ~~~ Yii によって供給されるクッキーバリデーションを利用するためには、`$_COOKIES` に直接アクセスする代わりに、[cookies|CHttpRequest::cookies] コレクションを通してクッキーにアクセスする必要があります。 ~~~ [php] // 特定の名前のクッキーを取得します。 $cookie=Yii::app()->request->cookies[$name]; $value=$cookie->value; ...... // クッキーを送ります。 $cookie=new CHttpCookie($name,$value); Yii::app()->request->cookies[$name]=$cookie; ~~~