クロスサイトスクリプティングの脆弱性とその対策

クロスサイトスクリプティングはユーザーの入力を受け付ける動的なアプリケーションに含まれる脆弱性を利用した攻撃です。
英語ではCross Site Scriptingと呼ばれその頭文字をとるとCSSとなりますが、「Cascading Style Sheets」との区別が紛らわしいため一般的にXSSの表記が使われています。

クロスサイトスクリプティングとはどのような脆弱性であるのか

XSSとは動的なWebサイトのプログラムの脆弱性を利用した攻撃です。
この脆弱性を利用することで、攻撃者は悪意のあるJavaScriptコードをサイトに埋め込み、そのコードを実行することができるようになります。

例えば、XSSの脆弱性がある掲示板があったとします。
攻撃者はフィッシングサイトにページを遷移させるJavaScriptコードを投稿しました。
すると、他の利用者がこの掲示板を閲覧したときにそのJavaScriptコードが実行され、フィッシングサイトが表示されるようになります。

この脆弱性を持ったサイトが攻撃されるとどのような被害が起き得るのか

上記の例のようにXSSはWebサイトの利用者を攻撃の対象とします。

例えば、以下のような被害が出る可能性があります。

  • ユーザーのcookie情報を盗み、その情報を利用してそのユーザーでログインする
  • 不正なページへユーザーを誘導する
  • 不正なファイルをダウンロードさせる

Webサイトを直接攻撃することも可能です。
JavaScriptのhtmlを書き換える機能を使って、攻撃対象のサイトの内容を書き換えることができてしまいます。

なぜそのようなセキュリティホールが作り込まれてしまうのか

HTMLには特殊文字が存在します。
具体的には「’”<>&」といった文字です。
これらの特殊文字をHTML上に表示するには適切な方法で変換しなければなりません。
しかし、XSSの脆弱性のあるプログラムはこのような特殊文字を意識せずに作られてしまっています。

どのように対策をすればよいのか

入力時のチェックと出力時のチェックを行います。

入力時のチェック

具体的には、入力時に入力できる文字を制限します。
例えば、郵便番号を入力するフォームの場合は、数字と-しか入力できないようにします。
そうすれば、悪意のあるコード自体が入力できなくなります。
入り口でとめる作戦です。

注意点としては、入力文字のチェックは必ずサーバサイドで行わなければなりません。
PHP等のサーバサイドで実行されるプログラムでチェックする必要があるということです。
クライアントサイド(JavaScript)のチェックでは攻撃者がそのチェック機構自体を無効にすることが可能です。

出力時のチェック

実際には仕様上、入力文字を制限することができないことがあります。
例えばフリーフォームの場合、無闇に入力文字を制限するとユーザーは自由に文章を入力することができなくなってしまいます。

そこで、出力時に文字を無害化(サニタイジング)します。

サニタイジングについては、プログラム言語やフレームワークに専用の機能が用意されています。
その機能を使うことを強く推奨します。

例えばPHPであれば、htmlspecialcharsというhtmlの特殊文字を無害化する関数が用意されています。
http://php.net/manual/ja/function.htmlspecialchars.php

また、フレームワークはデフォルトでサニタイズされた文字が出力される仕組みになっているはずなので、そのようなフレームワークを使ったほうがよいでしょう。

参考リンク