ブログに戻る
技術 公開:27.08.2026 1分で読めます

CAPTCHA はあるのに、何も守っていない

reCAPTCHA、hCaptcha、Turnstile のウィジェットが見えても、フォームが保護されているかはほとんど分かりません。典型的な設定ミスと、数分で自分のフォームを確認する方法を紹介します。

多くのサイト運営者は、お問い合わせフォームに CAPTCHA を追加し、小さなバッジやチェックボックスが表示されると、スパム問題は解決したと考えます。それでも、ごみのようなメッセージは届き続けます。CAPTCHA 自体には問題がなく、ボットを止められる仕組みにつながっていないだけ、ということもよくあります。この記事では、reCAPTCHA、hCaptcha、Cloudflare Turnstile が飾りになってしまう典型例と、自分のフォームの確認方法を説明します。

実際に保護が行われる場所

三つのサービスは、すべて同じ原理で動きます。ブラウザーのスクリプトがチェックを行い、「この訪問者は合格した」という短い文字列のトークンをフォームに渡します。トークンはフォームの送信とともにサーバーへ届きます。実際の判断が行われるのは、そこです。サーバーはトークンとシークレットキーを提供者へ送り、成功か失敗かの回答を受け取ります。reCAPTCHA v3 ではスコアも返ります。このつながりのどこかが欠けても、ウィジェットは正常に見えますが、フォームの処理先へ直接送るボットはそのまま通ってしまいます。

CAPTCHA が依存する一連の処理
1スクリプトを読み込む
提供者のスクリプトがフォームのページに読み込まれ、実行を許可される。
2トークンを発行
ブラウザーが、一度だけ使える短い有効期間のトークンを受け取る。
3トークンを送信
フォームの入力内容とともに、トークンをサーバーへ送る。
4サーバーで検証
サーバーがシークレットキーを使い、提供者にトークンを確認する。
5サーバーが判断
回答が肯定的でない場合(v3 ではスコアが十分高くない場合も)、送信を拒否する。
すべての段階が機能して初めて保護になります。決定的な段階は、見えないサーバー上で行われます。

すべてを通してしまうテストキー

Google、hCaptcha、Cloudflare は、パズルを解かずに開発者が自動テストを行える特別なテストキーを公開しています。対応するテスト用シークレットキーを使えば、検証は常に成功します。それが目的だからです。ローカル環境やステージング環境向けですが、本番への移行後も残ることがよくあります。開発者が構築中に貼り付け、サイトを公開し、誰も交換しないのです。reCAPTCHA は少なくともウィジェットにテスト専用の表示を出しますが、見えない設定ではほとんど誰も見ません。テスト用サイトキーとテスト用シークレットキーの両方が本番にあると、人でもボットでも、すべての送信が通ります。サイトキーだけがテストキーの場合は逆に検証に失敗し、本物のメッセージが拒否されることがあります。

誰も確認しないトークン

二つ目の典型例は、提供者にまったく問い合わせないサーバーです。ウィジェットが動き、トークンが作成、送信されても、フォームの処理コードが単に無視します。手作りのフォーム、ブラウザー側しか扱わないコピーしたコード片、未完了のプラグイン設定などが典型的な原因です。似たケースとして、サーバーは検証サービスを呼ぶものの、リクエストが通ったかだけを調べ、回答の内容を見ない場合があります。また、reCAPTCHA v3 のスコアしきい値を 0 にすると、サービスが返すすべてのスコアを受け入れます。「フェイルオープン」の処理もあります。トークンがない場合や検証に失敗した場合でもメッセージを受け入れるため、ボットはトークンを省くだけです。

ウィジェットが実際には読み込まれない場合

別の設定ミスは、ブラウザー側を壊します。サイトキーがそのドメインに登録されていないと、提供者はトークンの発行を拒否し、ウィジェットやブラウザーコンソールにエラーを表示します。ステージングから本番への移行、ドメイン変更、新しいサブドメインでよく起きます。テーマの変更やプラグインの更新後、ページにウィジェットのマークアップだけが残り、動かすスクリプトが消えることもあります。Cookie 同意ツールが、訪問者の同意まで CAPTCHA スクリプトをブロックする場合も同じです。その後どうなるかはサーバー次第です。有効なトークンを必須にすると、本物の訪問者が送信できなくなり、問い合わせを失っていることに誰も気付きません。必須にしなければ、ボットが自由に通ります。

さらに、見落としやすいケースが二つあります。reCAPTCHA v3 の隅のバッジは、テーマや別のプラグインなどにより、ページのどこかでスクリプトが読み込まれていることしか示しません。フォームプラグイン自体の連携は無効な場合があります。また、キャッシュプラグインが HTML に埋め込まれたトークンごとページを保存することがあります。CAPTCHA のトークンは数分しか有効でなく、検証も一度だけなので、キャッシュしたトークンは本物の訪問者に対して失敗します。チェックを無効にするという手軽な「修正」は、気付かぬうちに保護を取り除きます。

見た目と実態
見えているもの
  • ウィジェットに「for testing purposes only」と表示される
  • 隅に v3 のバッジがある
  • ウィジェットが表示され、トークンを返す
  • スパムは止まったが、本物の問い合わせも止まった
実際に起きている可能性
  • 公開テストキーが使われ、すべての検証が成功する
  • フォームプラグインの reCAPTCHA 連携は無効
  • サーバーがトークンを検証に送らない、または結果を無視する
  • ドメインにサイトキーが登録されていない、またはキャッシュしたトークンが期限切れ

簡単な自己チェック

  1. 1プライベートウィンドウでフォームのページを開き、ブラウザーの開発者ツールを開いて、コンソールに CAPTCHA スクリプトのエラーがないか調べます。
  2. 2Cookie バナーへの同意前と同意後の両方で、ウィジェットが実際に表示されること、表示されない状態ではフォームを送れないことを確認します。
  3. 3提供者の管理画面で、サイトキーに本番ドメイン(www などの別形式も含む)が登録されていること、フォームプラグインやコードのキーがそれと一致し、文書やステージング環境のキーではないことを確認します。
  4. 4フォームプラグインの設定で、このフォームに対する CAPTCHA 連携が有効かを確認します。reCAPTCHA v3 では、スコアしきい値が 0 より大きいことも確認します。
  5. 5コードにアクセスできる場合は、サーバー側の検証を探し、回答が否定的な場合やトークンがない場合に送信を拒否することを確認します。
  6. 6フォームのページをページ全体のキャッシュから除外するか、トークンをブラウザーで毎回新しく作成するようにします。
  7. 7実際のテストメッセージを送り、届くことを確認します。テーマ、プラグイン、同意ツールを変更した後も繰り返してください。
外側からのチェックで分かること、分からないこと
テストキー、スクリプトのないウィジェットのマークアップ、コンソールエラー、ブロックされたスクリプトは、外側から分かります。formexposed.com の無料チェックは、何も送信せず、まさにこれらの兆候を探します。サーバーが本当にトークンを検証するかは、ページからは見えません。サーバーのコードか、実際の送信でしか確認できません。

CAPTCHA は一つの層であり、保護のすべてではありません。ハニーポット欄、時間チェック、サーバー側のフィルターと組み合わせれば、一箇所の設定ミスでフォームが無防備になるのを避けられます。フォームの現状を手早く把握したい場合は、formexposed.com にドメインを入力してください。CAPTCHA の設定のうち、外側から見える部分が適切かどうかをレポートで確認できます。