WEBデザイナーの為のXSS(クロスサイトスクリプティング)入門

情報処理推進機構のXSS(クロスサイトスクリプティング/Webアプリケーションに存在するセキュリティホール)が公開されて、ネット上では盛り上げっているようです。

まぁ、これを機会にXSS(クロスサイトスクリプティング)って言葉をはじめて聞いたデザイナー・プログラマーの方は、正しい知識・正しい対処法を勉強しましょう。

とくにプログラムなんてちょっと改造するだけというレベルの、WEBデザイナーさんに注意してもらいたいです。

XSSはwebページにスクリプトを埋め込む攻撃法方法

XSSは別のサイト(これはどこでも良い)から攻撃先のurlに対して特定の文字列を送ることにより攻撃先のurlでスクリプトを実行する攻撃方法です。

XSS脆弱性のあるスクリプトはこんなスクリプトである。

<input type="hidden" name="name"value="<?php print $_POST[name]; ?>">

POSTやGETで送られたデータをそのまま表示してるスクリプトです。

実は、PHPの勉強で最初に覚えるこのようなスクリプトが、XSS脆弱性を含んでいるのです。

まずは結論

先ほどのコードからXSS脆弱性を取り除いたコードです。

<input type="hidden" name="name" value="<?php print htmlspecialchars($_POST[name]); ?>">

POSTやGETで送られたデータをそのまま表示せず、htmlspecialcharsを一度通してから表示します。
これで大体のXSS脆弱性はなくなります。

次からは、詳しい説明。
(プログラムに興味がない方は、結論だけもう一度読み返しといてください。)

攻撃方法

セキュリティホールの防御は、攻撃方法を理解した上で施工します。
防御方法だけ覚えていたのでは、何の応用もできません。


上記のスクリプトが記述されたwebページは以下のような(X)HTMLで攻撃が可能です。

<body onload="document.getElementById('f').submit()">
 <form action="攻撃先のurl" method="post" id="f">
  <input type="text" name="name" value='"><script>攻撃方法</script><"'>
 </form>

この(X)HTMLが仕込まれたwebページに訪れた人(Aさん)は攻撃先のurl(Bサイト)に自動的に移動することになります。

その際に、Bサイトでは以下のようなhtmlソースが出力されます。

<input type="hidden" name="name"value=""><script>攻撃方法</script><"">

つまり、AさんはBサイトで攻撃方法に記述されているjavascriptを実行することになります。

攻撃方法の記述しだいではAさんのBサイトのクッキーに保存されている情報攻撃者は取得できることができます。

攻撃方法はこれ以上詳しく書きませんが、Googleなどでだれでも簡単に攻撃方法の検索は可能です。

タグをそのまま出力出来るスクリプトはXSS脆弱性を含んでいます

防御方法は以下のとおりです。

<input type="hidden" name="name"value="<?php print strip_tags($_POST[name]); ?>">

strip_tagsを使い$_POST[name]内に存在するタグをすべて削除します。
こう記述しておけば先ほどの攻撃を受けた場合、表示されるソースは以下のとおりです。

<input type="hidden" name="name"value="">攻撃方法">

script要素が取り除かれている為、Bサイトでjavascriptが実行されることはなくXSS脆弱性はなくなりました。

めでたしめでたし。

と、行きたい所がそうはいきません。

XSS脆弱性は奥が深い

じゃ以下のような攻撃をうけたらどうでしょう

<body onload="document.getElementById('f').submit()">
 <form action="攻撃先のurl" method="post" id="f">
  <input type="text" name="name" value='" onmouseover="攻撃方法;'>
 </form><

表示されるソースは次のようになります。

<input type="hidden" name="name"value="" onmouseover="攻撃方法">

valueの最初に"が出力されている為、そのあとのonmauseover(イベントハンドラ)が実行可能な状態で出力されます。

$_POST[name]内にタグがない為strip_tagsは意味がありません。

イベントハンドラを出力できるスクリプトはXSS脆弱性を含んでいます

防御方法は以下の通りです。

<input type="hidden" name="name" value="<?php print htmlspecialchars($_POST[name]); ?>">

POSTやGETのデータを出力する前にhtmlspecialcharsを使いHTMLの特殊文字を実態参照に変換します。

出力されるhtmlソースは以下のようになります。

<input type="hidden" name="name" value="&quot; onmouseover=&quot;攻撃方法">

"が&quot;に変換されている為、出力される文字列が全てvalueの値として認識されます。

また、このhtmlspecialcharsを使うと<は&lt;に>は&gt;に変更される為、strip_tagsを使わなくてもスクリプト要素などの実行を防げます。

再び結論

つまり、XSSを防ぐためにはhtmlspecialcharsを使いましょう

その他のXSS脆弱性

以下のコードにもXSS脆弱性が含まれます。

<input type="hidden" name="name" value='<?php print htmlspecialchars($_POST[name]); ?>'>

これはvalueの区切り文字が'(シングルクオーテーション)の為、通常のhtmlspecialcharsではXSSを防げません。

<input type="hidden" name="name" value='<?php print htmlspecialchars($_POST[name],ENT_QUOTES); ?>'>

このようにhtmlspecialcharsに引数ENT_QUOTESを追加することによりシングルクオーテーションも実体参照化してXSSを防ぐ事が必要になります。

防ぐことができないXSS脆弱性

以下のようなXSS脆弱性は防御することが不可能です。このような記述は絶対しないようにしましょう。

■イベントハンドラ内にPOSTやGETの値を表示数するスクリプト

<input type="button" onclick="location.href='<?php print $_POST[url] ?>'">

■scirpt要素内ににPOSTやGETの値を表示数するスクリプト

<script type="text/javascript">
 documet.write("こんばんわ、<?php print $_POST[name] ?>さん");
<script>

これらはhtmlspecialcharsでは防げません。

他にもXSS脆弱性は多数あります。
完全に安全なスクリプトは無理でも少しでも安全なスクリプトを記述するよう心がけましょう。

スポンサードリンク

«アルファ画像を扱うalphafilter.jsライブラリ | メイン | サーチエンジン対策のカリスマが教える検索キーワード「超」起業術—クレジットカード1枚で始めて年商1億円!-鈴木 将司»