XSS 対策をしよう :: PHP でそれっぽいフォームを作成する その2
前回はそれっぽいフォームを書いてみました。
http://kwsktr.hatenablog.com/entry/2014/02/24/080941
解ってはいるけれど、欠点だらけです。
実際にちょっとだけ使ってみると、修正したい場所、気になる場所が浮き彫りになってきます。
form.php
- メールアドレスのバリデート処理は <input type="email"> だけでは足りない。
- <input type="email"> の動作はブラウザ依存で、中途半端。
result.php
thanks.php
上記の5つの問題点をちょっとずつ修正していこうと思います。
まずは、セキュリティの部分を修正しましょう。
XSS (Cross Site Scripting) の対策
外部からの入力文字列には htmlspecialchars() を使うなどして、html で意味を持つ特殊な文字列をエンティティに変換する必要があります。
すなわち $_POST['email'] の部分が、問題の箇所です。
外部からの入力は、$_GET、$_POST は当然として、URL なども該当しますので出力する際には忘れずに処理する必要があります。
result.php 変更後
<!doctype html> <html lang = "ja"> <head> <meta charset = "UTF-8"> <title>確認ページ</title> </head> <body> <h1>メールアドレスを確認してください</h1> <!-- 送信された email を表示 --> <table> <tr> <td>メールアドレス</td> <td> <?php echo htmlspecialchars($_POST['email'], ENT_QUOTES, 'UTF-8'); ?> </td> </tr> </table> <p>正しければ確認を押してください</p> <p> <a href="form.php">戻る</a> <a href="thanks.php">確認</a> </p> </body> </html>
htmlspecialchars 関数の詳しい説明は省きますが、オプションの指定として、ENT_QUOTES と正しい文字コードは必ずセットで記述してください。
外部入力を扱う際に、htmlspecialchars とオプションを書くのが面倒だったりするので、h 関数を作成するのが定番だったりしますね。
<?php function h($var) { if (is_array($var)) { // $var が配列だったら... // $var の各要素に h 関数を適用する return array_map('h', $var); } else { // $var が配列じゃなかったら、htmlspecialchars の処理 return htmlspecialchars($var, ENT_QUOTES, 'UTF-8'); } }
PHP逆引きレシピ 第2版 (PROGRAMMER’S RECiPE)
posted with amazlet at 14.02.24