Cloud Service
Turnstile
画像選択などの手間をユーザーに課さずボットを判別する次世代CAPTCHA代替。フォーム保護やログイン画面の不正利用対策を、無料かつ低摩擦で導入できる。
- 1.画像パズルなしで人間とボットを見分ける、ユーザー体験を損なわないCAPTCHA代替。
- 2.サイトに埋め込むウィジェットと、サーバー側で結果を検証するsiteverify APIの二段構成。
- 3.ログインフォームや問い合わせフォームなど、任意のWebサイトに単体でも導入できる。
解決する課題
- 会員登録・ログイン・問い合わせフォームへの自動化されたスパム送信やクレデンシャルスタッフィングを防ぎたい
- 従来型CAPTCHAの画像選択やゆがんだ文字入力がユーザー体験を損ない、離脱率を上げてしまっている
- 特定ベンダーの検証サービスに縛られず、サイトを問わず埋め込めるボット対策を導入したい
- ボット判定のために個人情報や広告目的のトラッキングを増やしたくない
- モバイル・低速回線でも軽量に動作する検証手段が欲しい
主要概念と用語
- ウィジェット(Widget): 保護対象のページに埋め込む検証部品。多くの場合、目に見えるチャレンジを出さずに裏側で完了する
- サイトキー(Site Key): フロントエンドに埋め込む公開用の識別子。ドメインごとに発行する
- シークレットキー(Secret Key): サーバー側だけが保持する秘密の鍵。siteverifyの呼び出しに使う
- トークン(Response Token): ウィジェットの検証完了後にクライアントへ発行される一時的な文字列。フォーム送信時にサーバーへ渡す
- siteverify: サーバーからトークンの正当性を検証するためのAPIエンドポイント。真偽と付随情報を返す
- マネージドチャレンジ(Managed Challenge): リスクに応じてCloudflareが自動的に検証の強度を調整するモード。多くの場合ユーザーに追加操作を求めない
- 非対話モード(Non-Interactive)/見えないモード(Invisible): 画面上のチェックボックス操作すら不要にする動作モード
- Widget Mode: 埋め込み時の表示形式(マネージド/非対話型/見えない型)を指定する設定
- プレクリアランス(Pre-Clearance): 一度検証をパスしたクライアントに対し、一定時間チャレンジを再提示しない仕組み
仕様・制限・クォータ
- ドメインごとにサイトキーとシークレットキーのペアを発行し、キーはサイト単位で管理する
- トークンには有効期限があり、発行から一定時間内にサーバー側で検証を完了させる必要がある
- 同一トークンをsiteverifyで検証できるのは一度きりで、再利用(リプレイ)はできない
- 開発・テスト用に、常に成功または常に失敗を返すテスト用の共有キーが公式に用意されている
- ウィジェットはJavaScriptの読み込みを伴うため、厳格なコンテンツセキュリティポリシー(CSP)を敷いている場合は許可設定が必要になる
- 提供中の主要な機能は無料枠の範囲で利用でき、料金体系は変動するため契約時の最新情報を確認する
本番のサイトキー・シークレットキーを使う前に、公式ドキュメントに掲載されているテスト専用の共有キーで、成功パターンと失敗パターンの両方を確認しておくと、本番導入時の切り分けが容易になります。
内部の仕組み
Turnstileは、ページに埋め込まれたウィジェットがブラウザ環境やネットワークの特徴、過去の挙動シグナルなどを裏側で複数の非対話的なチェックにかけ、多くの場合ユーザーに画像選択などの操作を要求せずに人間らしさを判定します。判定が難しい場合にのみ、軽量なチャレンジを追加で提示します。
検証が完了すると、ウィジェットは短命なレスポンストークンを発行し、フォームの隠しフィールドなどを通じてクライアントからサーバーへ送信されます。サーバーはこのトークンをシークレットキーとともにsiteverify APIへ送り、Cloudflare側でトークンの正当性・有効期限・重複利用の有無を検証します。
siteverifyは真偽値の判定結果に加えて、必要に応じてエラーコードやチャレンジのタイムスタンプなどの付随情報を返します。アプリケーションはこの結果を見て、フォーム送信やアカウント作成などの後続処理を許可するかどうかを決定します。判定はクライアント側の見た目の操作だけでなく、必ずサーバー側での検証を経て初めて信頼できる状態になります。
ウィジェットが画面上で成功表示を出しても、それだけでは十分ではありません。クライアントから送られてきたトークンをサーバー側でsiteverifyに送って検証しない限り、細工されたリクエストで判定を偽装される可能性があります。フロントエンドの表示とバックエンドの検証は必ずセットで実装してください。
設計パターン / ベストプラクティス
- フォーム送信前に必ずサーバー側検証を挟む: トークンの検証が成功するまで、実際の登録処理やメール送信などの副作用を実行しない
- マネージドチャレンジを既定にする: 個別のモードを細かく作り込むより、リスクに応じて自動調整されるマネージドチャレンジを基本にすると運用の手間が減る
- 重要フォームごとにウィジェットを分離: ログイン・登録・パスワードリセットなど攻撃対象になりやすい画面ごとにサイトキーやウィジェット設置を検討する
- 失敗時のフォールバック導線を用意: ウィジェットの読み込みに失敗した場合でも、ユーザーが完全にブロックされないよう代替手段やエラーメッセージを設計する
- レート制限や既存のWAFルールと併用: Turnstile単体に頼らず、異常な送信頻度の検知や既存のセキュリティ機構と組み合わせて多層防御にする
- CSPやSRIなど既存のセキュリティヘッダーとの整合を確認: ウィジェットのスクリプト読み込み元を許可リストに追加し、他のセキュリティ設定を壊さないようにする
運用・監視
- ダッシュボードでウィジェットごとのチャレンジの発行数や成功率などの傾向を確認できる
- siteverify呼び出しのエラーコードをアプリケーションログに記録し、キーの設定ミスやトークン期限切れなどの原因を切り分けられるようにする
- 正規ユーザーからの問い合わせで「フォームが送信できない」といった声が増えた場合、ウィジェットの表示モードやCSP設定を見直す
- キー(サイトキー/シークレットキー)のローテーションや無効化はダッシュボードまたはAPIから行い、漏えい時に速やかに再発行できる体制を整えておく
- 本番導入前後でスパム送信数やアカウント作成の異常値を比較し、効果測定を行う
コスト
| 項目 | 課金の考え方 | 備考 |
|---|---|---|
| ウィジェット表示 | 基本的な利用は無料枠で提供 | サイト数やアクセス規模により条件は変動しうる |
| siteverify呼び出し | サーバー側の検証リクエストに応じた扱い | アプリケーションの実装次第で呼び出し回数が変わる |
| 高度な機能 | 分析やエンタープライズ向け機能で条件が異なる場合がある | 詳細は契約プランに依存 |
具体的な無料枠の範囲や上限は変わりやすいため、導入前に公式の料金・プランページで最新の内容を確認してください。一般的な用途では追加コストをかけずに導入できる位置づけのサービスです。
セキュリティ
- サーバー側検証の徹底: クライアント側の見た目の成功表示だけで判断せず、必ずsiteverifyでトークンを検証してから重要な処理を実行する
- シークレットキーの厳重な管理: シークレットキーはサーバー環境変数やシークレットストアで管理し、フロントエンドのコードや公開リポジトリに含めない
- トークンの使い回し防止: レスポンストークンは一度きりの利用を前提に設計されているため、アプリケーション側でも再送や使い回しを許容しない実装にする
- プライバシーへの配慮: 画像選択のような個人の識別性が高い操作を避け、必要最小限のシグナルで判定する設計思想を理解して運用する
- 多層防御の一部として位置づける: Turnstileは入口の選別を担うものであり、認可・レート制限・WAFなど他の防御層と組み合わせて初めて十分な保護になる
シークレットキーをクライアント側のJavaScriptに埋め込んでしまう、あるいはsiteverifyの呼び出しを省略してトークンの存在だけで判定してしまうのは典型的な失敗です。いずれもボットや攻撃者に検証プロセスを迂回されるおそれがあるため、必ずサーバー側でシークレットキーを使ったトークン検証を行ってください。
関連サービス・比較
同じくフォームやアプリケーションへの不正トラフィックを制御する仕組みとして、WAFのレート制限やBot Managementが関連サービスに当たります。Turnstileは主に「人間かどうかを入力操作の摩擦なく判定する」役割を担い、WAFやBot Managementはリクエスト全体のパターンやルールベースの制御を担う点で位置づけが異なります。
| 観点 | Turnstile | WAF / Bot Management |
|---|---|---|
| 主な役割 | フォーム等での人間/ボット判定 | リクエスト全体のルールベース制御 |
| ユーザー体験 | 多くの場合、追加操作なしで完了 | ユーザーには基本的に見えない |
| 導入対象 | 特定のフォームやページ単位 | ゾーン全体やルート単位 |
| 判定基盤 | ウィジェット+siteverifyトークン検証 | シグネチャ/挙動スコアリング |
| 組み合わせ | 他のセキュリティ機能と併用が前提 | Turnstileと組み合わせ可能 |
ハンズオン / CLI例
Turnstileのウィジェット作成や設定変更は主にダッシュボードまたはCloudflare APIから行います。wranglerで認証情報を確認したうえで、APIを直接呼び出す例を示します。
# wranglerでCloudflareアカウントへの認証状態を確認
wrangler whoami
# ウィジェット(サイトキー/シークレットキーのペア)を作成
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/challenges/widgets" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"name": "contact-form-widget",
"domains": ["example.com"],
"mode": "managed"
}'
# 作成済みウィジェットの一覧を確認
curl -X GET "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/challenges/widgets" \
-H "Authorization: Bearer ${CF_API_TOKEN}"
# サーバー側でクライアントから受け取ったトークンをsiteverifyへ送信して検証
curl -X POST "https://challenges.cloudflare.com/turnstile/v0/siteverify" \
-H "Content-Type: application/json" \
--data '{
"secret": "'"${TURNSTILE_SECRET_KEY}"'",
"response": "'"${CLIENT_RESPONSE_TOKEN}"'"
}'
siteverifyのレスポンスに含まれる成功可否のフィールドを確認し、成功時のみフォーム送信やアカウント作成などの処理を進める実装にしてください。失敗時はエラーコードをログに残しておくと、設定ミスと実際の不正アクセスの切り分けがしやすくなります。
Cloudflare Service
Turnstileを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
セキュリティ・ID
比較で見る軸
クラウド: Cloudflare / カテゴリ: セキュリティ・ID / 難易度: basic
導入後に効く点
サイトに埋め込むウィジェットと、サーバー側で結果を検証するsiteverify APIの二段構成。
先に潰すリスク
サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。
- クラウド
- Cloudflare
- カテゴリ
- セキュリティ・ID
- 難易度
- basic
- 関連資格
- —
- 設計柱
- security / operational
判断チェックリスト
- 自社の用途が「セキュリティ・ID / security」に近いか確認する。
- 強みである「画像パズルなしで人間とボットを見分ける、ユーザー体験を損なわないCAPTCHA代替。」が本当に評価軸になるか確認する。
- 注意点の「サービス単体ではなく、権限、ネットワーク、監視、課金、バックアップを含めて設計する必要がある。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。