Contact Form 7のスパム対策完全ガイド:3層防御でスパムを撃退
はじめに
お問い合わせフォームへのスパムメール、本当に厄介ですよね。
Google reCAPTCHAの有料化をきっかけに、Cloudflare Turnstileへ移行された方も多いと思います。しかし、Turnstileだけでは防ぎきれないスパムがあるのも事実です。
そこで本記事では、3つの対策を組み合わせた「3層防御」をご紹介します。
なぜ3層防御が必要なのか
それぞれの対策には得意・不得意があります。
| 対策 | 防げるもの | 防げないもの |
|---|---|---|
| Cloudflare Turnstile | 自動化されたボット | 人間によるスパム |
| ハニーポット | 単純なボット | 賢いボット、手動スパム |
| URL入力禁止 | URLを含むスパム全般 | URLを含まないスパム |
1つの対策で完璧に防ぐことは不可能です。しかし、3つを組み合わせることで、それぞれの弱点を補い合い、ほぼ全てのスパムをブロックできます。
3層防御の仕組み
実装方法
第1層:Cloudflare Turnstile
Turnstileの導入方法は割愛しますが、プラグイン「Simple Cloudflare Turnstile」を使えば簡単に設定できます。
第2層・第3層:functions.phpへの追記
以下のコードをfunctions.phpに追記してください。
<?php
/**
* ============================================
* Contact Form 7 スパム対策(3層防御)
* - 第2層:ハニーポットフィールド
* - 第3層:URL入力禁止
* ============================================
*/
/**
* --------------------------------------------
* 第2層:ハニーポットフィールド
* --------------------------------------------
* ボットはフォームの全項目を自動入力する傾向があります。
* 人間には見えない隠しフィールドを設置し、
* 入力があった場合はスパムと判定します。
*/
// ハニーポット用のショートコードタグを登録
add_action('wpcf7_init', 'add_honeypot_field_to_cf7');
function add_honeypot_field_to_cf7() {
wpcf7_add_form_tag('honeypot', 'honeypot_shortcode_handler');
}
// ハニーポットフィールドのHTML出力
function honeypot_shortcode_handler($tag) {
return '<div style="position:absolute;left:-9999px;top:-9999px;" aria-hidden="true">
<label for="website_url">ウェブサイト(入力しないでください)</label>
<input type="text" id="website_url" name="website_url" tabindex="-1" value="" autocomplete="off">
<label for="user_phone">電話番号確認(入力しないでください)</label>
<input type="text" id="user_phone" name="user_phone" tabindex="-1" value="" autocomplete="off">
</div>';
}
// ハニーポットのバリデーション
add_filter('wpcf7_validate', 'validate_honeypot_cf7', 10, 2);
function validate_honeypot_cf7($result, $tags) {
if (!empty($_POST['website_url']) || !empty($_POST['user_phone'])) {
$result->invalidate('honeypot', 'エラーが発生しました。しばらくしてから再度お試しください。');
error_log('Spam detected via honeypot from IP: ' . $_SERVER['REMOTE_ADDR']);
}
return $result;
}
/**
* --------------------------------------------
* 第3層:URL入力禁止
* --------------------------------------------
* スパムメールのほとんどはURLを含んでいます。
* URL入力を禁止することで、スパムの目的達成を阻止します。
*/
// テキストフィールドにフィルターを追加
add_filter('wpcf7_validate_text', 'validate_no_urls_in_text', 20, 2);
add_filter('wpcf7_validate_text*', 'validate_no_urls_in_text', 20, 2);
add_filter('wpcf7_validate_textarea', 'validate_no_urls_in_textarea', 20, 2);
add_filter('wpcf7_validate_textarea*', 'validate_no_urls_in_textarea', 20, 2);
// URLを許可するフィールド名を定義
function get_url_allowed_fields() {
return array(
'url', // 会社URL用フィールドなど
'website', // Webサイト用フィールドなど
);
}
// テキストフィールドのURL検証
function validate_no_urls_in_text($result, $tag) {
$name = $tag->name;
if (in_array($name, get_url_allowed_fields())) {
return $result;
}
$value = isset($_POST[$name]) ? trim($_POST[$name]) : '';
if (check_for_url_patterns($value)) {
$result->invalidate($tag, 'URLやリンクを含めることはできません。');
}
return $result;
}
// テキストエリアのURL検証
function validate_no_urls_in_textarea($result, $tag) {
$name = $tag->name;
if (in_array($name, get_url_allowed_fields())) {
return $result;
}
$value = isset($_POST[$name]) ? trim($_POST[$name]) : '';
if (check_for_url_patterns($value)) {
$result->invalidate($tag, 'URLやリンクを含めることはできません。');
}
return $result;
}
// URLパターンの検出
function check_for_url_patterns($value) {
if (empty($value)) {
return false;
}
$patterns = array(
'#https?://#i',
'#www\.[a-z0-9-]+\.[a-z]{2,}#i',
'#[a-z0-9-]+\.(com|net|org|info|biz|co\.jp|jp|cn|ru|tk|ml|ga|cf|gq)\b#i',
'#bit\.ly|tinyurl|goo\.gl|ow\.ly#i',
'#[a-z0-9-]+\.link|\.click|\.top#i',
);
foreach ($patterns as $pattern) {
if (preg_match($pattern, $value)) {
return true;
}
}
return false;
}
Contact Form 7側の設定
フォーム編集画面で、ハニーポット用のショートコードを追加します。
[honeypot]
[text* your-name placeholder "お名前"]
[email* your-email placeholder "メールアドレス"]
[textarea* your-message placeholder "お問い合わせ内容"]
[submit "送信"]
[honeypot]は画面に表示されませんが、必ずフォーム内に記述してください。
各対策の詳細解説
第1層:Cloudflare Turnstile
Googleの「私はロボットではありません」に代わる認証システムです。
メリット
- 無料で利用可能
- ユーザーの操作不要(多くの場合)
- プライバシーに配慮した設計
限界
- 人間が手動で送信するスパムは防げない
- 高度なボットは突破する可能性がある
第2層:ハニーポットフィールド
人間には見えない「罠」のフィールドです。
仕組み
- 画面外に隠しフィールドを設置
- 人間には見えないので入力されない
- ボットは全項目を埋めようとする
- 入力があればスパムと判定
メリット
- ユーザー体験を損なわない
- 実装が簡単
限界
- 賢いボットは隠しフィールドを無視する
- CSSの隠し方を検出するボットもいる
第3層:URL入力禁止
スパムの「目的」を潰す対策です。
なぜ効果的か
スパムの目的は、ほぼ確実に「悪意のあるサイトへの誘導」です。そのため、スパムメールには必ずURLが含まれています。URL入力を禁止すれば、スパマーは目的を達成できません。
メリット
- ボット・手動スパム両方に効果的
- スパムの根本的な目的を阻止
注意点
- 正規ユーザーがURLを送信できなくなる
- 必要に応じて許可リストを設定する
カスタマイズ
URL許可フィールドの追加
会社URLなど、特定のフィールドでURLを許可したい場合は、get_url_allowed_fields()に追加します。
function get_url_allowed_fields() {
return array(
'url',
'website',
'company-url', // 追加
'reference', // 追加
);
}
検出ドメインの追加
スパムでよく使われるドメインを追加できます。
'#[a-z0-9-]+\.(com|net|org|info|biz|co\.jp|jp|cn|ru|tk|ml|ga|cf|gq|xyz|pw|cc)\b#i',
エラーメッセージの変更
$result->invalidate($tag, 'お問い合わせ内容にURLを含めることはできません。参照サイトがある場合はサイト名でお知らせください。');
導入時の注意点
正規ユーザーへの配慮
URL入力禁止により、正規ユーザーが「参考URL」などを送信できなくなります。
対策例
- フォームに「URLは入力できません」と明記する
- 「参照サイトがある場合はサイト名をご記入ください」と案内する
- URL入力用の専用フィールドを用意し、許可リストに追加する
テスト方法
導入後は必ずテストしてください。
- 正常な内容で送信 → 送信成功を確認
- URLを含めて送信 → エラー表示を確認
- 許可フィールドにURL入力 → 送信成功を確認
まとめ
| 層 | 対策 | 役割 |
|---|---|---|
| 第1層 | Cloudflare Turnstile | ボットを自動判定 |
| 第2層 | ハニーポット | 単純ボットを検出 |
| 第3層 | URL入力禁止 | スパム内容をブロック |
この3層防御により、スパムメールを大幅に削減できます。
それぞれ単独では限界がありますが、組み合わせることで弱点を補い合い、強固な防御が実現できます。
導入はfunctions.phpへのコード追記と、フォームへの[honeypot]追加だけです。ぜひお試しください。

