メールフォームを作る

もくじ > Web開発ノート > 独自開発CMS+PHP

Webサイトの役割は、見て欲しい人に見てもらい、お互いを必要とする人同士を繋げる事です。そのためにも重要な存在となるのがメールフォームです。

しかし、これを悪用して、ネットにある無数のメールフォームを自動的に検出するプログラムを作っている人がいます。そのプログラムはフォームに自動で内容を入力し、自動送信されるようになっています。そして出来る限り多くの人に無差別に何かの目的のメールが送られます。

もし世界中の数百万人に「今すぐお金を払わないとこのパソコンを壊します。振込先口座は〇〇〇」といったような根拠のない嘘を書いた脅迫メールを自動送信したら、その数百万人のうちの何人がいくら振り込んでくるでしょうか? そんな悪い事をどこかの誰かがいつも考えており、そんなプログラムはずっと動き続けていたりするわけです。

そんな犯罪的なアイデアを募集するためにメールフォームを公開しているわけではありません。できるかぎりの対策を練り、メールフォームを守る仕組みを組み込みましょう。

こちらにPikodon Companyのメールフォームがあります。

このメールフォームでは、迷惑メールや無差別に自動送信するスパムメールへの対策を考えては、実験的に実装してみてはアップデートしています。実際にどんな対策をしているのか、ここで紹介いたします。

ブラックリスト処理をつける

特定のメールアドレスから、繰り返し必要のない迷惑なメールが届くようでしたら、サーバ処理を通す前にメールフォームにブラックリスト機能をつけてしまうと良いでしょう。

ブラックリストに入れる判断をするためにも、どんなメールアドレスからどんな内容のものが送られているのかを記録しておくのも良いかもしれません。

しかし、そういった迷惑メールは送信元メールアドレスや、送信元サーバを偽装し、絶えず変化させている場合も多いです。

メールアドレスである事を判別する処理の例
$usermail = $user_data[$key]['data'];

$ret = preg_match("/^[a-zA-Z0-9_\.\-]+?@[A-Za-z0-9_\.\-]+$/", $usermail);
if(!$ret){
    $err = true;
}else if((mb_strlen($usermail) < 5) || (mb_strlen($usermail) > 120)) {
    $err = true;
}

NGワード処理をつける

どんなに送信元を変えても、メールの内容は工夫のない同じ文章を使っていたりします。例えば、大手PCメーカーを名乗り「あなたのアカウントはロックされました」とかいう内容を送ってくるメールは、送信元は同じですが、毎度同じ電話番号や連絡先が書いてあったりします。その電話番号をNGワードにすると、迷惑メールが減るかもしれません。

メールフォームの判別処理レベルで、ブラックリストに加えて、NGワード処理も加え、送信完了したふりをして、送信せず、記録だけ残せばサーバに負担もかからないでしょう。

しかし、連絡先さえも細かく変化させている場合もあります。

入力内容を制限する

データをダウンロードするサービスで、「私はロボットではありません。」のチェックマークを付けたり、「信号機はどれですか?全てを選んでください。」といったような事を求められる事があります。

これは、自分が悪意のある自動送信プログラムでない事を証明する手続きです。メールフォームでこういったプログラムを実装させている場合はあまりありません。こういった事を面倒臭がってせっかくのお客様を取り逃がしてしまうかもしれないからです。

日本で事業をしていて、お客さんを日本語でコミュニケーションできる人に限定したサービスの場合、メールフォームの内容に全角文字が使われていなかったら拒否するといった処理をつけてしまう事もできます。

この対策をするだけでも、ロシアから来る大量のスパムや、ドメイン更新詐欺で有名なNew York main officeの事務所からのメールが届かなくなるかもしれません。

全角文字判別コード
$str = $user_data[$key]['data'];
$len = mb_strlen($str, "UTF-8");
$wdata = mb_strwidth($str, "UTF-8");
if($len == $wdata) {
    $err = true;
}

最も危険な送信完了画面

メールフォームの流れとして、入力画面→確認画面→送信完了画面といった流れになっている場合が多いですが、この3つの画面の中で、悪意のある人に狙われると最も危険な画面はどれでしょうか?

答えは送信完了画面です。

入力画面は大抵は以下のようなHTMLコードになっています。formタグなどで入力項目を用意し、ユーザーに情報を入力してもらいます。

<form action="contact.php" method="post">
 <label>お名前</label>
  <input id="name" type="text" name="name">
 <label>メールアドレス</label>
  <input id="email" type="email" name="email">
 <label>本文</label>
  <textarea rows="8" name="comment"></textarea>
  <input type="submit" value="確認する">
</form>

その入力内容をPOST送信し、受け取った情報を表示するのが、確認画面です。ここでユーザーは自分が入力したものが正しいかどうかを最終確認し、送信ボタンを押します。

<form action="contact.php" method="post">
 <label>お名前</label>
  <?php echo $_POST['name']; ?>
 <label>メールアドレス</label>
  <?php echo $_POST['email']; ?>
 <label>本文</label>
  <?php echo $_POST['comment']; ?>
 <input name="name" type="hidden" value="<?php echo $_POST['name']; ?>" />
 <input name="email" type="hidden" value="<?php echo $_POST['email']; ?>" />
 <input name="comment" type="hidden" value="<?php echo $_POST['comment']; ?>" />
 <input type="submit" value="送信する">
</form>
//※注意:実際はこのような不用心な書き方をしてはいません

確認画面の送信ボタンを押して必要なデータをPOST送信し、そのデータを受け取り、実際にメール送信処理を実行するのが、送信完了画面となります。

foreach ($_POST as $key => $value){ 
    $message .= $value."\n"; 
} 
$to = $toMail;
$subject = 'メールが届きました';
$headers = 'From: '.$fromMail.' <'.$fromMail.'>';

mb_send_mail($to, $subject, $message, $headers);
//※実際はこんな不用心な書き方をしてはいけません

つまり、送信完了画面に対して、悪意のあるデータをPOST送信すれば、送信完了画面はそれを素直に受け取ってメール送信してしまいます。

例えば、ウィルスや詐欺内容のデータを第三者のメールアドレスに送るようにPOST送信すれば、送信完了画面は為すがままにそれに従ってしまうという事です。

送信完了画面には、第三者による送信や悪意のあるアクセスから守る処理をできるだけ多く組み込まなくてはなりません。

選択項目をつける

ここまで、不正な処理を行うプログラムや、世界中のメールフォームを無差別に狙う悪意のある者や、しつこく付きまとってくる特定の他者への対策方法をまとめてきました。

しかし、意外と困るのが悪意がない迷惑メールです。

必要としない営業をしてきたり、そもそもこのホームページのどこを読んで連絡をしてきたのかわからないようなコンタクトなど、お互いに時間の無駄としか思えないアポイントなど、新サービスを宣伝したい営業さんの時間つぶしのような絨毯営業だったり、ネズミ講のお誘いだったり、人材派遣会社だかの営業だったり、情報商材を買わせようとするだけのものだったりします。

そういったコンタクトに対しての対策として考えたのが、一番最初に選択項目をつけて、目的を選んでもらう方法です。

例えば、有名なPCメーカーの販売サイトに「ご購入される場合はメールから連絡ください」とだけ書いてあったとしたら、自社製品の紹介メールを送る迷惑メールや、全く無関係なオレオレ詐欺みたいなメールを送る人がいるかもしれません。

しかし、もし、「どんな製品をお探しですか? デスクトップパソコン、ノートパソコン、タブレット」などの選択項目があれば、それだけで目的の入り口がない事に戸惑い、去っていく場合も多いでしょう。

ここのメールフォームでは、「サービスの案内などはご遠慮ください。」と表記し、要件の一番最初のデフォルト項目を「サービスの案内」としました。

読まずに次の画面に行けば、お断り画面になり、メールが送信できなくなります。日本語が読めずに無差別に送るロボット処理や、外国の詐欺メール軍団も、この入り口のところで追い払う事ができるかもしれません。

ホワイトリストを作る

最後にメールに関する参考知識です。

送信者を特定しないメールフォームでは使えないものですが、メールサービスを使っているサーバ上でホワイトリストを作り、受信許可するメールアドレスや取引先の企業ドメインなどを登録しておきます。

そして、MailBoxの中の.mailfilterというファイルに、メールの受信に関する分岐や判別処理を書く事ができます。

例えば以下の文を記載すると、許可したメールアドレス以外は全て迷惑メールフォルダに入れられて届かなくなります。

if ( ! ( /^From:\s*(.*)/ && lookup( $MATCH1, ".whitelist" ) ) )
{
    to "maildir/.spam/"
}
if ( /^X-Spam-Flag:.*YES/ )
{
    to "maildir/.spam/"
}