kwsktr's study log

kwsktr のおべんきょログ

XSS 対策をしよう :: PHP でそれっぽいフォームを作成する その2

前回はそれっぽいフォームを書いてみました。
http://kwsktr.hatenablog.com/entry/2014/02/24/080941

解ってはいるけれど、欠点だらけです。
実際にちょっとだけ使ってみると、修正したい場所、気になる場所が浮き彫りになってきます。

form.php

  • メールアドレスのバリデート処理は <input type="email"> だけでは足りない。
    • <input type="email"> の動作はブラウザ依存で、中途半端。

result.php

  • $_POST['email'] をそのまま表示している
    • セキュリティ的に問題がある(XSSが未対策)
  • 戻るを押したら、入力内容が消えている
    • 入力したメールアドレス消えると全部最初から入力するのが手間
  • form.php からではなく、直接 result.php にアクセスした時の処理がない
    • 入力していないのに「メールアドレスを確認してください」が表示するのはおかしい

thanks.php

  • form.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)
鈴木 憲治 山田 直明 山本 義之 浅野 仁 櫻井 雄大 安藤 建一
翔泳社
売り上げランキング: 7,683