PHP コンタクトフォームのセキュリティ強化
今回は以前制作したコンタクトフォームのカスタム
具体的にはセキュリティ対策の強化及び使用するUIの変更などでもっとしっかりと作り込まれたフォームにしていきたいと思います
クロスサイトリクエストフォージェリ対策(CSRF攻撃)
クロスサイトリクエストフォージェリとはフィッシングサイトなどから直接的にお問合せフォームのサーバーにアクセスされ送信されてしまうことを言います。
具体的には通常お問合せフォームの入力画面から確認画面を通って送信の処理に移行するのですが悪意のあるサイトからの侵入によって勝手に送信の処理をさわる事もできてしまいます。
見に覚えのないメールが届いたりサーバーを攻撃されることによりサイトダウンに追い込まれたりとの危険性があります。
これを防ぐためにはどう対策するか、、
まずはお問い合わせの仕組みを考えます
入力するとともに合言葉(トークン)を作成してともにサーバーに送信する。
ここで①で作成したトークンの整合性が取れれば送信処理をする。
ここでfalseになると送信を中断するようにする
②での判定で送信結果報告をする、
この流れでいけそうですね
トークンの生成処理を行う
PHPでは便利な関数が用意されていて
PHP5のとき
$token = bin2hex(mcrypt_create_iv(32,MCRYPT_DEV_URANDOM));
PHP7のとき
$token = bin2hex(random_bytes(32));
この関数でランダムな文字列が64バイトの暗号が生成され特にPHP7の関数は暗号論的にしっかりと証明されているとかなんとか、、
このコードを見えないように仕込んでいきます
まず確認画面に行く際に、値を送信された入力内容をチェックする構文があると思います
ここのタイミングで入力内容にエラーがなければ処理を追加します
$token = bin2hex(random_bytes(32));
$_SESSION['token'] = $token;
生成したトークンをセッション変数に格納します
次にこれを送信するためのタグを書きます
生成されたトークンは画面をまたいで変数にセットされ確認画面にページ遷移したとします
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>"/>
上記の一文をHTMLのformタグの中に追記します
これで確認画面から変数トークンが一緒に送信されるようになりました
最後に送信処理の部分にトークンの判定を追記します
if (!$_POST['token'] || !$_SESSION['token'] || !$_SESSION['email']) {
$err_msg = '不正な処理が行われたためメールを送信できませんでした。';
unset($_SESSION);
$mode = 'input';
} else if ( $_POST['token'] !== $_SESSION['token']) {
$err_msg = '問題が発生したためメールを送信できませんでした。';
unset($_SESSION);
$mode = 'input';
} else {
//・・正常なメール送信処理
}
最上部のif文で、変数にそもそもトークンがないとき、またわ、セッション変数にトークンがない時、またわ送信者のメールアドレスが無い時
そして
変数トークンとセッション変数のトークンが一致しない時にエラーになるように処理を追加し
それらに引っかからなければ通常の送信処理を行うようにします。
これで不正に対する対策は問題なさそうですね
コメントをお待ちしております