お問い合わせ、登録、チェックアウトのフォームは、自動化された不正利用の標的になりやすいです。このガイドではフォーム保護を扱います。訪問者が人間であることを確認し、繰り返しの送信を制限し、既知の攻撃パターンをブロックします。中核の手順は、すべてのプランで利用できる機能を使います。Pro と Business プランの機能は、補足として記載します。
Turnstile は、目に見えるチャレンジなしで、訪問者が人間であることを確認します。このガイドでは Managed モードを使います。訪問者のリスクレベルに応じて、非インタラクティブなチャレンジとチェックボックスのチャレンジを自動で選びます。その他のウィジェットモードは、ウィジェットの種類 を参照してください。
Turnstile の追加は 3 ステップです。ダッシュボードでウィジェットを作成し、フォームページにクライアント側のスニペットを追加し、送信を処理する前にサーバーでトークンを検証します。
-
Cloudflare ダッシュボードで Turnstile ページを開きます。
Turnstile を開く ↗ -
Add widget を選択します。
-
必要な情報を入力します。
- Widget name: ウィジェットのわかりやすい名前です。
- Hostname management: ウィジェットを使うドメインです。
- Widget mode: Managed、Non-Interactive、Invisible から選びます。
-
(任意)シングルページアプリケーション向けに Pre-clearance support を設定します。
-
Create を選択してウィジェットを保存します。
-
sitekey とシークレットキーをコピーし、シークレットキーは安全に保管します。
サイトキーとシークレットキーを保存します。サイトキーはクライアント側のスニペットで、シークレットキーはサーバー側の検証で使います。
保護したい各フォームに、Turnstile のスクリプトとウィジェットの div 要素を追加します。<YOUR-SITE-KEY> は、前の手順のサイトキーに置き換えます。
<form id="contact-form" action="/submit" method="POST">
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required></textarea>
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
<button type="submit">Submit</button>
</form>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>ウィジェットはフォーム内に表示され、訪問者が検証に通るとトークンを生成します。トークンは、cf-turnstile-response フィールドとしてフォーム送信に含まれます。
サーバー側の検証は必須です。クライアント側のウィジェットだけではフォームを守れません。攻撃者はフォームのエンドポイントへ直接送信できるためです。トークンは 1 回だけ検証できます。
フォーム送信を処理する前に、Siteverify API を呼び出します。
const SECRET_KEY = "<YOUR-SECRET-KEY>";
async function validateTurnstile(token, remoteip) {
try {
const response = await fetch(
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
secret: SECRET_KEY,
response: token,
remoteip: remoteip,
}),
},
);
const result = await response.json();
return result;
} catch (error) {
console.error("Turnstile validation error:", error);
return { success: false, "error-codes": ["internal-error"] };
}
}"<YOUR-SECRET-KEY>" を、Turnstile のシークレットキーに置き換えます。エンドポイントは success フィールド付きの JSON オブジェクトを返します。success が true の場合にだけ、フォーム送信を処理してください。
PHP、Python、Java、C# での検証例は、トークンを検証する を参照してください。
一部の不正利用スクリプトはブラウザーを経由せず、フォームのエンドポイントへ直接 POST します。クライアント側の検証はブラウザー内だけで動くため、Application Security の レート制限ルール が、こうしたリクエストを捕捉します。
レート制限ルールを作成する前に、フォームエンドポイントの通常の送信レートを確認します。正当なトラフィックをブロックしないよう、レート制限のしきい値はこの基準より上にしてください。
-
Cloudflare ダッシュボードで、Analytics ページを開きます。
Analytics を開く ↗ -
Traffic タブで、ピークではない期間、または訪問者アクティビティが最も低い期間を選びます。
-
フィルターを追加 ボタンを使い、フォームエンドポイントのトラフィックに絞り込みます。
-
IP アドレスあたりの典型的なリクエストレートを記録します。レート制限は、この基準より上にしてください。
基準を決めるのに十分なトラフィックデータがない場合は、控えめなしきい値から始め、デプロイ後に Security Events を見て調整します。
1 つの IP アドレスが、一定期間内にフォームエンドポイントへ送信できる回数を制限するルールを作成します。パス、しきい値、期間は、サイトに合わせて調整してください。
-
Cloudflare ダッシュボードで Security rules ページを開きます。
Security rules を開く ↗ -
Create rule を選び、Rate limiting rules を選びます。
-
ルール名を入力します(例: "お問い合わせフォームの送信をレート制限する")。
-
When incoming requests match で Edit expression を選び、次を入力します:
「/contact」をお使いのフォームエンドポイントのパスに置き換えます。(http.request.uri.path eq "/contact" and http.request.method eq "POST") -
With the same characteristics で、IP が選ばれていることを確認します。Free プランでは、この値は IP に固定されています。
-
When rate exceeds で、Requests に 5 を入力し、Period の値を選びます。Free プランでは 10 seconds を選びます。Pro 以上のプランでは、ほかの期間も選べます。プランごとの利用可能な値は、レート制限パラメーター を参照してください。
-
Then take action で、Choose action ドロップダウンからアクションを選びます。Free プランでは Block を選びます。Pro 以上では、上限に達した正規ユーザーがチャレンジを完了して通過できるため、Managed Challenge をおすすめします。
-
For duration で、アクションの継続時間を選びます。Free プランでは 10 seconds を選びます。Pro 以上のプランでは、より長い継続時間も選べます。これは、レート制限がトリガーされたあと、アクションが適用される時間です。
-
Deploy を選びます。
レート制限に達したときに、デフォルトの Cloudflare エラーページではなく、カスタムレスポンスを表示できます。詳細は ダッシュボードでレート制限ルールを作成する を参照してください。
レート制限だけでは、フォーム欄への SQL インジェクションやクロスサイトスクリプティング(XSS)のような、狙った攻撃パターンは捕捉できません。Application Security の カスタムルール と マネージドルールセット で、フォームエンドポイントを狙うこうした具体的なパターンをブロックできます。カスタムルールは、実行順 ではレート制限ルールとマネージドルールセットより先に実行されます。
検証済みボット以外からの、フォームエンドポイントへの POST リクエストにチャレンジするカスタムルールを作成します。
-
Cloudflare ダッシュボードで、Security rules ページを開きます。
Security rules を開く ↗ -
Create rule > Custom rules を選択します。
-
ルール名を入力します(例: 「お問い合わせフォームのスパム送信にチャレンジする」)。
-
When incoming requests match で Edit expression を選択し、次を入力します。
(http.request.uri.path eq "/contact" and http.request.method eq "POST" and not cf.client.bot)/contactは、お使いのフォームエンドポイントのパスに置き換えます。not cf.client.botの条件は、検証済みボット(検索エンジンのクローラーなど)をルールから除外します。 -
Then take action で Managed Challenge を選択します。
まず Managed Challenge で、どのリクエストがフラグ付けされるかを観察してから、Block に切り替えてください。
-
Deploy を選択します。
デプロイ後、Security Events を確認し、ルールが正当なトラフィックに一致していないかを調べます。正当なユーザーがチャレンジされている場合は、式を狭めるか、より緩いアクションに切り替えます。
Bot Fight Mode は、ドメイン全体で既知のボットパターンに一致するリクエストにチャレンジします。すべてのプランで利用でき、オンにする以外の設定は不要です。
-
Cloudflare ダッシュボードで Security Settings ページを開きます。
Settings を開く ↗ -
Bot traffic で絞り込みます。
-
Bot fight mode を開きます。
-
Bot fight mode をオンにします。
Bot Fight Mode は、エンドポイントの制限なしでドメイン全体を保護します。カスタムルールで例外を作り、Bot Fight Mode を回避することはできません。
Turnstile、レート制限ルール、Application Security ルールをデプロイしたあと、フォームエンドポイントを監視し、ルールが動作していることと、新しい攻撃パターンを検出します。
Security Events は、Cloudflare のセキュリティ製品が対処またはフラグ付けしたリクエスト(ブロック、チャレンジ、スキップを含む)を表示します。フォームエンドポイントのパスで絞り込み、何がブロックされ、何が通過しているかを確認します。フォームパスへのブロックまたはチャレンジが多い場合、ルールが有効だと判断できます。
-
Cloudflare ダッシュボードで、Analytics ページを開きます。
Analytics を開く ↗ -
Events タブを選択します。
-
フィルターを追加 ボタンを使い、フォームエンドポイントのトラフィックに絞り込みます。
-
サンプリング済みログを確認します。各イベントで次を調べます。
- 実行したアクション: リクエストがブロック、チャレンジ、許可のいずれだったか
- ソース: アクションを発動したルールまたは機能
- IP アドレス: 1 つの IP が多数のイベントを生成していないか
- URI パス: リクエストがフォームエンドポイントを特に狙っていないか
正当なユーザーがチャレンジされている場合は、ルール式を狭めるか、より緩いアクションに切り替えます。
ドメイン上のセキュリティイベントが通常と異なる急増をしたときに通知を受け取るよう、通知を設定します。
アラートの種類、発動しきい値、設定手順は、セキュリティイベントのアラート を参照してください。
サードパーティスクリプトがフォームページに注入されると、決済情報を含む送信データを窃取できます。Client-Side Security は、ページ上のサードパーティスクリプトの変更と、サプライチェーン攻撃の可能性を監視します。
監視を有効にする手順は次のとおりです。
-
Cloudflare ダッシュボードで、Security Settings ページを開きます。
Settings を開く ↗ -
(任意)Client-side abuse で絞り込みます。
-
Continuous script monitoring をオンにします。
有効にしたあと、Web assets ページの Client-side resources タブで検出されたスクリプトを確認し、フォームページ上の想定外のスクリプトがないかを調べます。セットアップ全体の流れは、Client-Side Security を利用する を参照してください。
Turnstile
- Turnstile を利用する — ウィジェットの作成、クライアントスニペットの追加、トークンの検証
- トークンを検証する — 複数言語でのサーバー側検証の例
- Turnstile、WAF、Bot Management を統合する — ログイン保護向けに 3 製品を組み合わせるチュートリアル
Application Security
- カスタムルール — 特定のリクエストパターンを対象にするルールを作成する
- レート制限ルール — 大量の不正利用からエンドポイントを保護する
- セキュリティ機能の相互運用 — セキュリティ機能の実行順と相互作用
Bots
- Bot Fight Mode — Free プランでボットパターンに一致するリクエストにチャレンジする
- Super Bot Fight Mode — Pro 以上向けの細かいボット制御
Client-Side Security
- Client-Side Security を利用する — 監視を有効にし、検出されたスクリプトを確認する