解 説

*それぞれのコードは「入力フォームのコード」「確認ページのコード」「メール送信のコード」をクリックすると見られます。

メール送信の仕組みを学習する上での参考例です。セキュリティ問題を完全に解決したものではありませんのでそのまま運用はしないでください。解説をよく読んでセキュリティ対策を理解した上で実験しましょう。完全運用するためには各自オリジナルのセキュリティ対策をしっかり行って使用してください。
サンプル フォームで入力した内容を一度確認した上でメール送信をします。その際に、入力もれや悪意のある入力対策を行います。
入力フォームのコード
確認ページのコード
メール送信のコード

解説

入力フォーム

入力フォームはPHP実習 (4)のものと基本的に変わりません。
変えた部分はセキュリティを考慮してtokenをつけました。
これはクロスサイトリクエストフォージェリ攻撃の対策です。md5(uniqid(mt_rand(), TRUE))はランダムな数字を作成しています。
この値を input type=”hidden” の値に設定して確認ページへ送ります。

確認ページのif文で判定して、もしフォームページから正規に送られたものでなければtokenが合わなくなりエラーとなる仕組みです。

けれども、これも完璧ではありません。
攻撃者がソケット通信などでワンタイムトークンを取得して、罠ページのhidden情報にそのトークンを注入して送信先することで回避できてしまいます。

参考サイトなど今後リンク予定

確認ページ

確認のページでは、URLのクエリに「PHPSESSID=……」という文字列をつけて攻撃してくる対策としてcookie以外のセッションIDを受け付けなくします。

ここではif文でフォーム入力が正しくできているかチェックします。

特に重要なポイントはメールアドレスの入力データです。
正しくメールアドレスが入力されているか正規表現パターンで判定します。
さらに、ポイントは単一のメールアドレスであることです。
ここのメールアドレスはそのまま、メール送信するための関数 mb_send_mail のヘッダー部分で使用します。
もし、このメールアドレスに改行を入れてbccなどのアドレスを入れると勝手なアドレスにメールが送信されることになります。この手法をメールヘッダーインジェクション脆弱性といいます。

メール送信

メール送信はサーバーの環境設定が正しくできていれば簡単です。
mb_send_mail()関数を使用すれば送信することができます。

メールヘッダーの指定方法
ヘッダー名: 値[改行]
ヘッダー名: 値[改行]
ヘッダー名: 値[改行]
・・・

主なメールヘッダー
分類 ヘッダ名 概要
基本 Content-Type メール本文のコンテンツタイプ
  Date 送信日時
  subject 件名
アドレス To 宛先
  Cc カーボンコピー
  Bcc ブライドカーボンコピー
  From 差出人アドレス
  Reply-To 返信アドレス
その他 Recieved メール送信に際しての中継サーバー
  X-Mailer 作成したメールソフト

mb_send_mailは正しく送信されるとtrueを返しますので、if文でメールの送信とエラーを表示させます。

$bodyへのデータの代入は本来次のようにするとわかりやすいかもしれません。$whatは配列になっています。これを取り出すにはforeach を使いたくなりますが、それではうまくいきません。この場合はimpload()を使用します。

$bodyへのデータの代入をもっと効率的に行ったのが次の方法です。

foreach文を使うことで$_SESSIONに入っている配列を取り出します。取り出したものをそのまま$bodyに書き込んだのが次の方法です。
このようにすることで、入力項目が変更になったり増えたり減ったりしてもこの部分を変更しなくても自動で書き出してくれるようになるわけです。