CAPTCHA はあるのに、何も守っていない
reCAPTCHA、hCaptcha、Turnstile のウィジェットが見えても、フォームが保護されているかはほとんど分かりません。典型的な設定ミスと、数分で自分のフォームを確認する方法を紹介します。
多くのサイト運営者は、お問い合わせフォームに CAPTCHA を追加し、小さなバッジやチェックボックスが表示されると、スパム問題は解決したと考えます。それでも、ごみのようなメッセージは届き続けます。CAPTCHA 自体には問題がなく、ボットを止められる仕組みにつながっていないだけ、ということもよくあります。この記事では、reCAPTCHA、hCaptcha、Cloudflare Turnstile が飾りになってしまう典型例と、自分のフォームの確認方法を説明します。
実際に保護が行われる場所
三つのサービスは、すべて同じ原理で動きます。ブラウザーのスクリプトがチェックを行い、「この訪問者は合格した」という短い文字列のトークンをフォームに渡します。トークンはフォームの送信とともにサーバーへ届きます。実際の判断が行われるのは、そこです。サーバーはトークンとシークレットキーを提供者へ送り、成功か失敗かの回答を受け取ります。reCAPTCHA v3 ではスコアも返ります。このつながりのどこかが欠けても、ウィジェットは正常に見えますが、フォームの処理先へ直接送るボットはそのまま通ってしまいます。
すべてを通してしまうテストキー
Google、hCaptcha、Cloudflare は、パズルを解かずに開発者が自動テストを行える特別なテストキーを公開しています。対応するテスト用シークレットキーを使えば、検証は常に成功します。それが目的だからです。ローカル環境やステージング環境向けですが、本番への移行後も残ることがよくあります。開発者が構築中に貼り付け、サイトを公開し、誰も交換しないのです。reCAPTCHA は少なくともウィジェットにテスト専用の表示を出しますが、見えない設定ではほとんど誰も見ません。テスト用サイトキーとテスト用シークレットキーの両方が本番にあると、人でもボットでも、すべての送信が通ります。サイトキーだけがテストキーの場合は逆に検証に失敗し、本物のメッセージが拒否されることがあります。
誰も確認しないトークン
二つ目の典型例は、提供者にまったく問い合わせないサーバーです。ウィジェットが動き、トークンが作成、送信されても、フォームの処理コードが単に無視します。手作りのフォーム、ブラウザー側しか扱わないコピーしたコード片、未完了のプラグイン設定などが典型的な原因です。似たケースとして、サーバーは検証サービスを呼ぶものの、リクエストが通ったかだけを調べ、回答の内容を見ない場合があります。また、reCAPTCHA v3 のスコアしきい値を 0 にすると、サービスが返すすべてのスコアを受け入れます。「フェイルオープン」の処理もあります。トークンがない場合や検証に失敗した場合でもメッセージを受け入れるため、ボットはトークンを省くだけです。
ウィジェットが実際には読み込まれない場合
別の設定ミスは、ブラウザー側を壊します。サイトキーがそのドメインに登録されていないと、提供者はトークンの発行を拒否し、ウィジェットやブラウザーコンソールにエラーを表示します。ステージングから本番への移行、ドメイン変更、新しいサブドメインでよく起きます。テーマの変更やプラグインの更新後、ページにウィジェットのマークアップだけが残り、動かすスクリプトが消えることもあります。Cookie 同意ツールが、訪問者の同意まで CAPTCHA スクリプトをブロックする場合も同じです。その後どうなるかはサーバー次第です。有効なトークンを必須にすると、本物の訪問者が送信できなくなり、問い合わせを失っていることに誰も気付きません。必須にしなければ、ボットが自由に通ります。
さらに、見落としやすいケースが二つあります。reCAPTCHA v3 の隅のバッジは、テーマや別のプラグインなどにより、ページのどこかでスクリプトが読み込まれていることしか示しません。フォームプラグイン自体の連携は無効な場合があります。また、キャッシュプラグインが HTML に埋め込まれたトークンごとページを保存することがあります。CAPTCHA のトークンは数分しか有効でなく、検証も一度だけなので、キャッシュしたトークンは本物の訪問者に対して失敗します。チェックを無効にするという手軽な「修正」は、気付かぬうちに保護を取り除きます。
- ウィジェットに「for testing purposes only」と表示される
- 隅に v3 のバッジがある
- ウィジェットが表示され、トークンを返す
- スパムは止まったが、本物の問い合わせも止まった
- 公開テストキーが使われ、すべての検証が成功する
- フォームプラグインの reCAPTCHA 連携は無効
- サーバーがトークンを検証に送らない、または結果を無視する
- ドメインにサイトキーが登録されていない、またはキャッシュしたトークンが期限切れ
簡単な自己チェック
- 1プライベートウィンドウでフォームのページを開き、ブラウザーの開発者ツールを開いて、コンソールに CAPTCHA スクリプトのエラーがないか調べます。
- 2Cookie バナーへの同意前と同意後の両方で、ウィジェットが実際に表示されること、表示されない状態ではフォームを送れないことを確認します。
- 3提供者の管理画面で、サイトキーに本番ドメイン(www などの別形式も含む)が登録されていること、フォームプラグインやコードのキーがそれと一致し、文書やステージング環境のキーではないことを確認します。
- 4フォームプラグインの設定で、このフォームに対する CAPTCHA 連携が有効かを確認します。reCAPTCHA v3 では、スコアしきい値が 0 より大きいことも確認します。
- 5コードにアクセスできる場合は、サーバー側の検証を探し、回答が否定的な場合やトークンがない場合に送信を拒否することを確認します。
- 6フォームのページをページ全体のキャッシュから除外するか、トークンをブラウザーで毎回新しく作成するようにします。
- 7実際のテストメッセージを送り、届くことを確認します。テーマ、プラグイン、同意ツールを変更した後も繰り返してください。
CAPTCHA は一つの層であり、保護のすべてではありません。ハニーポット欄、時間チェック、サーバー側のフィルターと組み合わせれば、一箇所の設定ミスでフォームが無防備になるのを避けられます。フォームの現状を手早く把握したい場合は、formexposed.com にドメインを入力してください。CAPTCHA の設定のうち、外側から見える部分が適切かどうかをレポートで確認できます。