最近、このブログのお問い合わせフォームや、Webスクール体験レッスン、メルマガ登録などのフォームにスパムボット(広告・宣伝などを自動で送信するプログラム)と思われる送信があまりにも多いため、対策をしています。
メールフォームのスパムポット対策と言えばGoogleの「reCAPTCHA」が有名ですが、 そういったものは使用せず、HTMLとサーバー側のPHPを工夫することで対策をしました。
reCAPTCHAを使わない理由
スパムボットを防ぐ有名な方法にGoogleのreCAPTCHAがありますが、以下の理由から私はできれば使用したくありません。
理由1: ユーザーに負担をかける
reCAPTCHAでは、ボットかどうか疑わしい場合、人間であることを確認するためのパズルが表示されます。
しかし、例えばメールマガジン登録フォームにメールアドレスを入力して送信しようとした際に、そのようなパズルが現れたら、大抵のユーザーは面倒に感じて登録を止めてしまうと思います。
ユーザーにストレスを与えてしまうため、できれば避けたいです。
理由2: ページの動作が重くなる
WordPressのお問い合わせフォームプラグインの中には、reCAPTCHAを設定できるものもあります。
しかし、設定するとブログ記事のすべてのページでreCAPTCHAのJavaScriptが読み込まれて動作が重くなり、ページの表示に時間がかかるようになってしまいました。
特定の固定ページのみプラグインを動作させる方法もありますが、その場合十分な精度が出ず、人間がメッセージを送信しようとしてもパズルが表示されてしまう可能性があります。
また、私のブログではトップページやすべての記事にメールマガジン登録フォームがあるため、この方法は使いたくありませんでした。
以上の理由から、reCAPTCHAを使わずに別の方法でスパム対策をすることにしました。
スパム対策1: nameをランダムな文字列にする
フォーム要素の名前を変更して、ボットを混乱させる
お問い合わせフォームのHTMLを見ると、以下のようなコードが使われていることが多いと思います。
<input type="text" name="name">
<input type="email" name="email">
<textarea name="message"></textarea>
nameやemailなどの名前は一般的なものなので、スパムボットにとって狙いやすい標的となってしまいます。
そこで、以下のように name をランダムな文字列に変更することで、ボットを混乱させます。
<label for="g6813">お名前</label>
<input type="text" name="g6813" id="g6813">
<label for="h2451">メールアドレス</label>
<input type="text" name="h2451" id="h2451">
<label for="i9204">本文</label>
<textarea name="i9204" id="i9204"></textarea>
input type=”email” を使用すると、 スパムボットにその欄がメールアドレスとバレてしまうので、input type=”text” を使用します。
これで、ボットにとってどの項目に何を入力すれば良いのか全くわからなくなります。
もちろん、フォームの処理を行うサーバーサイドのプログラムも、これらの要素名に合わせて修正する必要があります。
私の場合、PHPファイルの先頭付近で以下のように代入することで、それ以降のプログラムが見やすいようにしています。
// 変数をわかりやすい名前に置換
$name = $g6813;
$mail = $h2451;
$body = $i9204;
メールアドレスに @ が含まれていない場合、受信を拒否する
前述のように名前をランダムな文字列に変更すると、多くのスパムボットは「ランダムな4桁から6桁程度の半角の数字の羅列」を入力して送ってきます。
そこで、サーバーサイドで「メールアドレスに @ が含まれていない場合はエラーを表示し、送信しない」ようにします。
これだけで、多くのスパムボットを防ぐことができます。
注意点
このやり方の注意点は、例えば「メールアドレスの入力欄のnameだけをランダムな文字列にしていても意味がない」ことです。
メールアドレスだけではなく、名前と本文の入力欄など、複数の入力欄の name をランダム文字列にしていないと意味がありませんでした。
アクセシビリティへの配慮
input type=”email” ではなく、input type=”text” なのはアクセシビリティ的にはあまり良くないと感じる方もいらっしゃると思います。
アクセシビリティを重視する場合は、以下のようにJavaScriptを使ってinput type=”text”をtype=”email”に変更するという方法もあります。
<label for="h2451">メールアドレス</label>
<input type="text" name="h2451" id="h2451">
document.getElementById("h2451").type = "email";
ただし、JavaScriptが読めるボットが訪れた場合、スパムを送ってくる可能性があります。
そのような場合は、ダミーのemail入力フォームを作ってCSSで非表示にしておき、人間にはわかりやすいように「この項目には何も入力しないでください」とラベルをつけておきます。
(このような手法は、「ハニーポット」と呼ばれます。これはボットを誘い出すための罠です)
<label for="dummy_email">この項目には何も入力しないでください</label>
<input type="email" name="dummy_email" id="dummy_email" style="display: none;">
そして、ダミーのemail入力フォームに値が入力されていた場合は、サーバー側でエラーを表示して送信できないようにします。
スパム対策2: サーバーサイドでURLを含むメッセージをブロックする
スパムメッセージの多くは、本文中にURLを含んでいます。
そこで、本文に「http」という文字列が含まれている場合、サーバーサイドでエラーメッセージを表示して送信されないという方法もあります。
このブログのお問い合わせフォームには手動で広告や宣伝を送ってくる方もいるため、nameのランダム化だけでなく、この方法も併用しています。
スパム対策3: ラジオボタンを使用する
ほとんどのスパムボットは、以下のようにチェックボックスやラジオボタンの value の値を日本語にしている場合、サーバーに送信された value の値が文字化けしたり、”????” になります。
これを利用すれば、スパムボットからの送信を防ぐことができます。
HTMLは、項目が1つだけのラジオボタンを作ってchecked属性をつけることで、最初からチェックを入れておきます。
<input type="radio" name="human_check" value="文字化けチェック" checked>
サーバー側では送信された値が正しい内容かチェックする(この例の場合、”human_check” で送信された値が “文字化けチェック” という文字列に等しいか確認する)ことで、人間が送信したものか判別できます。
まとめ: 効果はあった?
このブログの場合、以下の対策を行っています。
メールマガジン登録フォームは以下のように入力項目が1つだけですが、ここでは「スパム対策1: nameをランダムな文字列にする」 を使用しています。
これだけでスパムと思われるメールマガジンの登録はなくなりました。
※私のメルマガにご登録いただくと、Web制作、WordPress、Web制作者のためのAI活用などの動画を無料で視聴頂けたり、動画講座に優先的にお申し込み頂けます。よろしければ以下からどうぞ。
お問い合わせフォームは、残念ながら name 対策を行っても人力で宣伝を送ってくる方がいたため、本文に「http」という文字列が含まれている場合は送信エラーにして、フォームの上部に以下のように注意書きを記載するようにしました。
広告、宣伝、人材関連等の売り込みはお断りします。
「本文」に http が含まれている場合、送信できませんのでご注意ください。
また、これは過去の経験則ですが、手動で何度もスパムを送ってくる方に対しては、「宣伝を送ってこないでください。今度送ってきたら、御社を迷惑メール送信事業者としてGoogleに通報します。」と返信すると、ほぼ100%の方が謝って、その後送信してこなくなります。
よろしければご活用ください。