なぜ既存プラグインがあるのに自分たちでスパム対策を作ったのか
私たちが保守しているクライアントのWordPressサイトでは、長らくある問題に悩まされていた。1日の問い合わせ件数がそれほど多くないフォームであっても、自動化されたスパムが深刻なノイズになりつつあったのだ。
「今週の問い合わせ、半分がスパムだったよ。仕分けるのが本当に面倒で……」
問題はゴミメッセージを削除する手間のことだけではない。最大の被害は、フォームそのものへの信頼がゆっくりと削られていくことだ。仮想通貨やSEOサービスの営業といった数十件のゴミ投稿の山から、2〜3件の本物のリードを探し出さなければならない日々が続くと、ビジネスと顧客をつなぐ最も重要な架け橋であるはずのコンタクトフォームが、ただの負債のように感じられてくる。これは Samurai Honeypot for Forms の開発ストーリーだ。私たちが標準的な選択肢を試し尽くした末に、なぜ独自のソリューションを作る決断をしたのか、そしてどんな技術的判断がこれを形作ったのかをまとめた。
現代のスパムの現実
私たちは数十のWordPressサイトを構築・保守している。そのほとんどで Contact Form 7 を使っている。軽量で柔軟だからだ。しかし、そのスリムな設計ゆえに、スパム対策はエコシステムに委ねられている。何年もの間、私たちはいろいろな対策を後付けしてきたが、2024年から2025年にかけて状況は大きく変わった。
ボットの進化
今や単純なスクリプトが相手ではない。現代のボットはしばしばヘッドレスブラウザを動かし、JavaScriptを実行し、CSSをレンダリングし、キーストローク間のタイミングまで人間のように振る舞う。大規模言語モデル(LLM)の統合により、本物のビジネス問い合わせにしか見えないメッセージまで生成されるようになり、従来のコンテンツフィルタは効きにくくなっている。
運用への影響
ビジネスオーナーが、たった数件の本当のリードを見つけるために数十件のゴミメッセージを仕分けなければならないとき、S/N比(シグナル対ノイズ比)は崩壊する。フォーム経由の問い合わせの確認を後回しにし、電話対応に頼り始めるクライアントも出てきた。Webサイトの最も重要なコンバージョンポイントが価値を失いつつあった。ユーザー体験を損なうことなく、この問題をもっと根本的に解決する方法が必要だった。
私たちが評価したもの
いきなりコードを書き始めたわけではない。車輪の再発明をするつもりはなく、単に私たちの特定の要件で機能するソリューションが欲しかっただけだ。数ヶ月かけて既存の選択肢をテストした。
カスタムチャレンジ(「日本クイズ」)
いくつかのプロジェクトで、文化に依存したシンプルな質問(例:「日本の郵便ポストの色は?」)を追加してみた。これは一夜にしてスパムをほぼゼロに減らしたが、2つの欠点があった。1つはプロフェッショナルなフォームのデザインを損なうこと。もう1つは、LLM搭載ボットがこうした「文化的」ハードルを簡単に突破できるようになるのは時間の問題だと分かっていたことだ。
コンテンツベースのフィルタ (Akismet)
Akismet は業界標準の堅牢なツールだが、主にコンテンツ(文面)を分析する。ユニークなAI生成スパムに対しては、コンテンツ分析だけでは信頼性が落ちてきている。さらに、私たちは高いデータプライバシー基準を維持するため、送信のたびにサードパーティのAPIに頼るのではなく、すべて自社サーバー内でデータを処理するソリューションを求めていた。
行動分析 (reCAPTCHA)
Google reCAPTCHA v2 と v3 は強力だが、トレードオフがある。v2 は(特にモバイルで)コンバージョン率を低下させる恐れがあり、見えないはずの v3 はページ読み込み時間に影響を与えたり、プライバシー重視のブラウザやVPNを使っている正当なユーザーを「疑わしい」と誤判定したりすることがあった。
標準的なハニーポットプラグイン
隠しフィールドのコンセプト自体は理にかなっているが、ほとんどのプラグインは静的な実装を使っている。ボットのスクリプトが hp_field というフィールドが display: none で隠されていると一度特定してしまえば、単にそれをスキップするだけだ。ボットがパターンを学習するため、これらのツールの効果は数週間で落ちてしまうことが多かった。
私たちのアプローチ:多層的、ローカル、そして軽量
私たちは腰を据えて、私たちのワークフローにおける理想のソリューションを定義した。目に見えるUIがなく、外部依存がなく、ボットの進化に耐性があること。これが Samurai Honeypot for Forms の設計仕様になった。
しかし、正直に白状すると、もう一つの理由があった。単に自分たちで作ってみたかったのだ。 開発者として、サードパーティのツールをツギハギして、アップデートやAPI制限の管理に追われるのにはうんざりしていた。独立した多形態(ポリモーフィック)の防御メカニズムを作るという課題は、エンジニアとして面白そうな問題に思えた。自分たちの手でゼロからエレガントなものを作りたかったのだ。
私たちの最初の試作品(社内コードネームで「Honey Potter」と呼ばれていた単一のハニーポット)は、実際にスパムの総量を劇的に減らすことに成功した。しかし稼働から11日目、私たちはログを見て気づいてしまった。低レベルなボットは防げているが、高度なヘッドレスブラウザボットには最初から素通りされている事実に。
「ここまで減らせたなら、このすり抜けてくる賢いスパムも全部捕まえたい」。このエンジニアとしての執着が、私たちを受動的な罠から、能動的に悪意を切り捨てる多層防御システム(刀)の開発へと駆り立てたのだ。
核心のアイデア:ポリモーフィック防御
予測可能なボットスクリプトに対抗するため、ポリモーフィック・ハニーポットを実装した。静的な名前ではなく、隠しフィールドの名前やCSSの隠し手法をページ読み込みのたびにローテーションする。DOMをスキャンするボットにとってフォームは毎回違って見えるため、一貫した「スキップ」ルールを作るのがはるかに難しくなる。
多層バリデーション
単一の手法で万能なものはない。罠を待つのではなく、能動的に悪意を切り捨てるため、私たちのプラグインは5つの独立したレイヤーを使用している:
- ポリモーフィック・ハニーポット: 標準的な自動スクリプトを捕捉する。
- 送信タイミング検証: フォームのレンダリング時に署名付きタイムスタンプを埋め込み、人間には不可能な速度(3秒未満など)での送信を弾く。
- クライアントサイド Proof of Work: ユーザーには見えない極小の計算パズルをブラウザに解かせることで、大量送信を行うボットにだけ高いコストを強いる。
- ステートレスHMACトークン: WordPressのnonceに依存せずにサーバーサイドで送信を検証し、強力なページキャッシュやCDNとの互換性を確保する。
- サイレント拒否: ボットを検出した際、エラーではなく成功メッセージを返す。これにより、ボットオペレーターがスクリプトをデバッグ・改善するためのフィードバックを与えないようにする。
技術的な抑制
プラグインの内部を意図的に「退屈(シンプル)」に保つよう努めた。依存関係を避けるためにバニラJavaScriptを使用し、Contact Form 7 の既存の送信パイプラインに直接フックしている。また、アクセシビリティも重視し、aria-hidden 属性を使用してハニーポットフィールドがスクリーンリーダーユーザーを混乱させないようにした。
道中で学んだこと
このツールを構築して学んだのは、決して「絶対に破られない壁」を作る必要はないということだ。単に、他の選択肢よりも攻撃コストを高くすればいい。シンプルなものであっても複数のレイヤーを追加することで、ボットオペレーターにとっての「成功した送信あたりのコスト」を引き上げ、彼らがもっと簡単なターゲットに移るように仕向けることができる。
また、プライバシーとパフォーマンスは直結していることも再確認した。すべてをローカルで処理することで、外部APIのレイテンシを排除し、ユーザーデータがクライアントの環境から決して出ないことを保証できた。
現在の状況
Samurai Honeypot for Forms は現在、WordPress公式プラグインディレクトリで公開されている。私たちはこれを自社のクライアントポートフォリオ全体で使用しており、「ゴミが減り、本物のリードが再びクリアに届くようになった」という一貫したフィードバックを得ている。
見えないセキュリティと外部依存ゼロを両立するツールが必要だったから作った。そして何より、自分たちで作るのが一番スッキリする解決策だったからだ。もしあなたが、同じような「インストールしたらあとは忘れていい」アプローチを探している開発者やサイトオーナーなら、これが役に立つことを願っている。
Samurai Honeypot for Forms は WordPress公式プラグインディレクトリ で無料公開中。私たちがいかにしてこの多層防御に行き着いたか、その泥臭い開発の裏側を知りたい方は、開発秘話『魔法使い「Honey Potter」から侍へ…【Samurai Honeypot】開発ストーリー』もぜひ読んでほしい。