クロスサイトスクリプティングとは、フォーム画面等の外部からの入力によってHTMLを出力する箇所の脆弱性をつく攻撃で、例えばユーザが入力した値をそのままブラウザで表示させてしまうと悪意のあるJavaScriptなどが実行されクッキーが盗まれるなどの危険があります。
デモ画面にて <h1>サンプル</h1> を入力し、送信してみて下さい。h1タグが反映されてサンプルの文字が大きく表示されてしまいます。
またFireFoxブラウザでデモ画面を開き、下記のJavaScriptコードを入力してみて下さい。画面遷移先でアラートが表示されてしまいます(ChromeやSafariはある程度対策されています)。
1 |
<script>alert("こんにちは")</script> |
上記デモ画面ではクロスサイトスクリプティングの対策を行っていないので、入力されて受け取ったスクリプトは、そのままブラウザに実行されてしまいます。これを予防するためには、値を表示させる直前に、値の中に含まれる特殊文字を無効にしなければいけません。これをエスケープと言います。
PHPでは、htmlspecialchars()関数を利用してエスケープすることができます。下記のコードでは受け取った値をエスケープして表示させています。
1 |
<?php echo htmlspecialchars($post_yourname, ENT_QUOTES, 'UTF-8'); ?> |
実際にこの処理を行ったデモ画面が下にあります。あらためて、 <h1>サンプル</h1> やアラートが表示されるJavaScriptコードを入力してみて下さい。遷移先の画面ではしっかりとエスケープされて表示されているのがわかります。
ただし、htmlspecialchars関数はHTMLテキスト用のエスケープ関数なので万全ではありません。例えば、 入力された値を、<a href=”◯◯◯”>sample</a>の◯◯◯のようなタグの中で出力する場合は、htmlspecialcharsだけでは対処できません。
試しに javascript:alert(‘Test’) という文字列が入力された場合を想定して、下記のコードのようにa hrefの属性に出力させてみます。$xssはhtmlspecialchars関数を通していますが、ブラウザで表示させるとアラートが表示されてしまいます。
1 2 3 4 |
<?php $xss = "javascript:alert('Test')"; echo '<a href="'.htmlspecialchars($xss, ENT_QUOTES).'">link</a>'; ?> |
このような場合は、入力時に正規表現でjavascriptが入っていないかをチェックしたり、「http://」や「https://」で始まる文字列のみを出力するなどの処理(ホワイトリスト方式)が必要となります。
関連ページ
ホワイトリスト方式[XSS][preg_match][htmlspecialchars]