サイトにログインページがある場合、訪問者が人かどうかをどう検証するか、失敗した試行をどの程度厳しく制限するか、どのリクエストパターンをブロックするかを決める必要があります。このガイドは 5 段階です。HTTPS を強制します。ボット対策をオンにします。ログインフォームに Turnstile を追加します。不審なパターン向けに Application Security の レート制限ルール と カスタムルール を作成します。SSL/TLS の通信セキュリティと Cloudflare のボットソリューション で、継続中の攻撃を監視します。中核のワークフローは、Free、Pro、Business プランで使える機能を対象にします。漏洩認証情報のカスタム検出場所や Bot Management のカスタムルールなど、Enterprise 向け機能は補足として記載します。
平文の HTTP で送った認証情報は、訪問者とオリジンサーバーの間のネットワーク経路上の誰からも見えます。Cloudflare SSL/TLS には、HTTPS 接続を強制する 2 つの設定があります。Always Use HTTPS と HTTP Strict Transport Security (HSTS) です。ドメインが受け入れる暗号化規格をさらに制御するには、暗号スイート を参照してください。
Always Use HTTPS は、すべてのサブドメインとホストについて、訪問者のリクエストを http から https へリダイレクトします。
ダッシュボードで Always Use HTTPS を有効にするには:
-
Cloudflare ダッシュボードで SSL/TLS Overview ページを開きます。
Overview を開く ↗ -
SSL/TLS 暗号化モード が Off になっていないことを確認します。暗号化モードを Off にすると、Cloudflare ダッシュボードに Always Use HTTPS が表示されません。
-
Edge Certificates ↗ ページを開きます。
-
Always Use HTTPS をオンにします。
API で Always Use HTTPS を有効または無効にするには:
- SSL/TLS 暗号化モード が Off になっていないことを確認します。
- URI パスの設定名に
always_use_httpsを指定し、valueパラメーターに希望の設定("on"または"off")を入れて、PATCHリクエストを送信します。
Cloudflare は、すべてのプランでボット対策を提供します。機能はプラン階層によって異なります。ログイン固有のルールを設定する前にボット対策をオンにすると、ドメイン全体の自動トラフィックに対するベースラインのフィルターになります。
Bot Fight Mode は、既知のボットパターンに一致するリクエストにチャレンジします。ドメイン上のすべてのトラフィックに適用され、例外やパス固有のルールではカスタマイズできません。
-
Cloudflare ダッシュボードで Security Settings ページを開きます。
Settings を開く ↗ -
Bot traffic で絞り込みます。
-
Bot fight mode を開きます。
-
Bot fight mode をオンにします。
Super Bot Fight Mode は、既知のボットのパターンに一致するトラフィックを識別し、ボットをチャレンジまたはブロックでき、静的リソースも保護します。ボットのグループごとに別のアクションを設定します。Definitely automated、Likely automated、Verified bots です。Application Security の カスタムルール で Skip アクションを使い、例外を設定 することもできます。
-
Cloudflare ダッシュボードで Security Settings ページを開きます。
Settings を開く ↗ -
Bot traffic で絞り込みます。
-
Super Bot Fight Mode を開きます。
-
Super Bot Fight Mode をオンにします。
-
各種類のトラフィックへの応答方法を、対応する編集アイコンを選んで設定します。
- 検証済みボットの詳細は、Verified Bots を参照してください。
- 対応ファイルタイプの詳細は、静的リソース保護 を参照してください。
- 不可視のコード注入の詳細は、JavaScript detections を参照してください。
- WordPress 最適化の詳細は、Super Bot Fight Mode for WordPress を参照してください。
ログイン保護では、次の値から始めることをおすすめします。トラフィックパターンに合わせて調整してください。
- Definitely automated: Managed Challenge。正当なトラフィックに影響しないことを Security Events で確認したあと、Block に切り替えます。
- Likely automated: Managed Challenge。
- Verified bots: Allow。
カスタムルール は Super Bot Fight Mode より先に実行されます。特定のパスやトラフィック向けの例外を作るには、Skip アクション のカスタムルールを作成します。Skip アクションは、リクエストを終了せずに Super Bot Fight Mode フェーズをバイパスさせ、セキュリティスタックの残りの処理へ進めます。
ログインエンドポイントを自動の不正利用から守るツールは 2 つあり、それぞれ別の攻撃経路をカバーします。
- Turnstile は、CAPTCHA を出さずに訪問者が人であることを検証します。トラフィックを Cloudflare 経由にしなくても、任意のウェブサイトに埋め込めます。自動のフォーム送信にチャレンジするときに使います。
- Application Security の レート制限ルール は、式に一致するリクエストのレート上限と、その上限に達したときのアクションを定義します。ブルートフォース攻撃など、ログインエンドポイントの不正利用を防ぐときに使います。
両方を組み合わせると、最も広くカバーできます。Turnstile はフォーム単位で自動送信にチャレンジします。レート制限は、フォームを迂回する、またはフォームに到達しない大量攻撃(エンドポイントへの直接 POST など)を捕捉します。
Turnstile の導入は 3 ステップです。ウィジェットを作成し、ログインフォームにクライアント側スニペットを追加し、サーバーでトークンを検証します。Turnstile は、明示的レンダリングと暗黙的レンダリングを含む複数の レンダリング方法 に対応します。ログインフォームのソースコードを制御できない場合は、Cloudflare Worker で HTML に Turnstile を注入 することもできます。
Turnstile はアカウントレベルで設定します。
-
Cloudflare ダッシュボードで Turnstile ページを開きます。
Turnstile を開く ↗ -
Add widget を選択します。
-
必要な情報を入力します。
- Widget name: ウィジェットのわかりやすい名前です。
- Hostname management: ウィジェットを使うドメインです。
- Widget mode: Managed、Non-Interactive、Invisible から選びます。
-
(任意)シングルページアプリケーション向けに Pre-clearance support を設定します。
-
Create を選択してウィジェットを保存します。
-
sitekey とシークレットキーをコピーし、シークレットキーは安全に保管します。
以降の手順では、sitekey と secret key の両方が必要です。
ログインフォームに Turnstile のスクリプトとウィジェット用コンテナを追加します。<YOUR-SITE-KEY> は、前の手順の sitekey に置き換えます。
<form id="login-form">
<input type="text" id="username" placeholder="Username" required />
<input type="password" id="password" placeholder="Password" autocomplete="off" required />
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
<button type="submit">Log in</button>
</form>
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async
defer
></script>ウィジェットは div 内に描画され、訪問者がチャレンジに合格するとトークンを生成します。フォーム送信時、フォームデータに cf-turnstile-response トークンが含まれます。
フォーム送信を処理する前に、トークンを Turnstile の siteverify エンドポイントへ送り、訪問者がチャレンジに合格したことを確認します。
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 の secret key に置き換えます。エンドポイントは success フィールドを含む JSON オブジェクトを返します。success が true のときだけ、フォーム送信を処理してください。
追加の不正検出として、Turnstile は Ephemeral IDs に対応します。個人データを保存せずに、訪問者セッションごとに一意で一時的な識別子を提供します。
レスポンス形式、エラーコード、ほかの言語の例は、トークンを検証する を参照してください。
Turnstile は、Siteverify API に接続せずに予測可能な結果を返すテスト用 site key を提供します。
- 常に合格: site key
1x00000000000000000000AAと secret key1x0000000000000000000000000000000AAを使い、成功したチャレンジをシミュレートします。 - 常にブロック: site key
2x00000000000000000000ABと secret key2x0000000000000000000000000000000AAを使い、失敗したチャレンジをシミュレートします。 - 対話型チャレンジを強制: site key
3x00000000000000000000FFを使い、対話型チャレンジの流れをテストします。
テストキーと想定動作の一覧は、Turnstile の実装をテストする を参照してください。
次の例は、同じ IP から 1 分以内にログインパスへ POST が 5 回を超えたときに Managed Challenge を出すレート制限ルールを作成します。最初は Block ではなく Managed Challenge から始めてください。Managed Challenge は、上限に達した正当なユーザーがチャレンジを完了して通過できるようにし、解けない自動トラフィックはブロックします。Security Events を監視し、誤検知が出ていないことを確認したあと、Block に切り替えます。パス(/login)、しきい値、期間は自サイトに合わせて調整してください。
-
Cloudflare ダッシュボードで Security rules ページを開きます。
Security rules を開く ↗ -
Create rule を選び、Rate limiting rules を選びます。
-
ルール名を入力します(例: "ログインエンドポイントのレート制限")。
-
When incoming requests match で Edit expression を選び、次を入力します:
`example.com` を自ドメインに、`/login` をログインエンドポイントのパスに置き換えます。http.host eq "example.com" and http.request.uri.path eq "/login" 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 を選びます。
クレデンシャルスタッフィングが長く続くサイトでは、厳しさを上げた複数のレート制限ルールのデプロイを検討してください。レート制限のベストプラクティス では、3 つのルールを使う段階的なペナルティパターンを説明しています。短時間ウィンドウのルールで急増を捉え、中時間ウィンドウのルールで遅い分散攻撃を捉え、長時間ウィンドウのルールで執拗な攻撃者をドメイン全体からブロックします。カウント式はレスポンスのステータスコードを使うため、成功したログインは上限に数えません。推奨しきい値と式の構文は、ベストプラクティスのページを参照してください。
Application Security の カスタムルール と トラフィック検出 は、リクエストレート以外のシグナルで、不審なログイントラフィックを識別して対処できます。検出は、漏洩認証情報の状態やボットスコアなどのリクエストフィールドを埋めます。カスタムルールから参照できます。
漏洩認証情報検出は、受信ログインリクエストをスキャンし、既知のデータ漏洩データベースに含まれるユーザー名とパスワードを探します。Cloudflare は照合前に認証情報をハッシュし、平文のパスワードは保存しません。一致が見つかると、カスタムルールとレート制限ルールで使えるフィールドが埋まります。
cf.waf.credential_check.password_leaked フィールドは、すべてのプランで利用できます。
Free プランでは、漏洩認証情報検出はデフォルトで有効であり、操作は不要です。有料プランでは、Cloudflare ダッシュボード、API、または Terraform で検出をオンにできます。
-
Cloudflare ダッシュボードで、セキュリティの Settings ページを開きます。
Settings を開く ↗ -
(任意)Detection tools で絞り込みます。
-
Leaked credential detection をオンにします。
次のような POST リクエストを使います。
Required API token permissions
At least one of the following token permissions is required:Zone WAF WriteAccount WAF Write
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/leaked-credential-checks" \
--request POST \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--json '{
"enabled": true
}'ゾーンで漏洩認証情報の検出を有効にするには、cloudflare_leaked_credential_check リソースを使います。次に例を示します。
resource "cloudflare_leaked_credential_check" "zone_lcc_example" {
zone_id = var.cloudflare_zone_id
enabled = true
}検出をオンにしたあと、オリジンサーバーは Exposed-Credential-Check リクエストヘッダーで漏洩認証情報の状態を受け取れます。このヘッダーを転送するには、Add leaked credentials checks header マネージド変換をオンにします。オリジンは、影響を受けたユーザーにパスワードリセットを促せます。
ログイントラフィックをチャレンジまたはブロックするルールをデプロイする前に、既知の正当な自動トラフィックを除外するスキップルールを作成します。これにより、監視ツール、ヘルスチェック、パートナー連携が、後続のルールでブロックされるのを防ぎます。
-
Cloudflare ダッシュボードで Security rules ページを開きます。
Security rules を開く ↗ -
Create rule を選び、Custom rules を選択します。
-
ルール名を入力します(例: 「既知クライアント向けにログインルールをスキップ」)。
-
Edit expression を選び、正当な自動トラフィックに一致する式を入力します。たとえば、検証済みボットと特定の監視サービス IP をスキップするには:
(cf.client.bot) or (ip.src eq 198.51.100.1)198.51.100.1を監視サービスの IP アドレスに置き換えます。ほかの既知クライアント向けの条件も追加します。 -
Then take action で Skip を選びます。WAF components to skip で、ログイン保護ルールに該当するコンポーネントを選びます(例: All remaining custom rules と All rate limiting rules)。
-
Deploy を選びます。
-
Place at で、ブロックとチャレンジのルールより上にこのルールを置きます。カスタムルールは順に実行されるため、スキップルールを先にする必要があります。
Skip アクションと利用できるスキップオプションの詳細は、Skip アクション を参照してください。
クレデンシャルスタッフィングツールは、標準的なブラウザヘッダーなしでリクエストを送ったり、既知の悪い User-Agent パターンを使ったりすることがよくあります。ログインパスへの POST で User-Agent が空のときに Managed Challenge を出すカスタムルールを作成します。curl、python-requests、undici など、User-Agent ヘッダーを設定しないツールからの直接 POST を対象にします。
-
Cloudflare ダッシュボードで Security rules ページを開きます。
Security rules を開く ↗ -
Create rule を選び、Custom rules を選択します。
-
ルール名を入力します(例: 「ログインで空の UA にチャレンジ」)。
-
Edit expression を選び、次を入力します。
(http.request.uri.path eq "/login" and http.request.method eq "POST" and len(http.user_agent) eq 0)/loginをログインエンドポイントのパスに置き換えます。 -
Then take action で Managed Challenge を選びます。
-
Deploy を選びます。
レート制限と漏洩認証情報検出を組み合わせ、既知の侵害済みパスワードを使うログイン試行を抑制します。このルールは、同じ IP が 1 分以内に漏洩パスワード付きリクエストを 3 回より多く送ったときに Managed Challenge を出します。
-
Security rules ページで Create rule を選び、Rate limiting rules を選択します。
Security rules を開く ↗ -
ルール名を入力します(例: 「漏洩認証情報をレート制限」)。
-
When incoming requests match で、次の式を入力します。
http.request.uri.path eq "/login" and http.request.method eq "POST" and cf.waf.credential_check.password_leaked/loginをログインエンドポイントのパスに置き換えます。 -
With the same characteristics で、IP が選ばれていることを確認します。Free プランでは IP に固定されています。
-
When rate exceeds で、Requests に 3 を入力し、Period の値を選びます。Free プランでは 10 seconds を選びます。
-
Then take action でアクションを選びます。Free プランでは Block を選びます。Pro 以上では Managed Challenge をおすすめします。
-
For duration で、アクションの継続時間を選びます。Free プランでは 10 seconds を選びます。
-
Deploy を選びます。
前のセクションのルールと設定をデプロイしたあと、ログインエンドポイントを監視し、ルールが機能していることと、新しい攻撃パターンを検出します。
Security Events は、Cloudflare のセキュリティ製品がアクションした、または検出対象にしたリクエストを表示します。ブロック、チャレンジ、スキップを含みます。
-
Cloudflare ダッシュボードで Analytics ページを開きます。
Analytics を開く ↗ -
Events タブを選びます。
Sampled logs を確認し、個々のリクエストを調べます。各ログエントリには、実行されたアクション、引き金になったルール、送信元 IP、ユーザーエージェント、URI パス、国が表示されます。Add filter ボタンで、アクション、送信元 IP、ASN、その他のフィールドで結果を絞り込めます。
誤検知(ルールが誤ってチャレンジまたはブロックした正当なトラフィック)を探します。よくある兆候は次のとおりです。
- 既知の監視サービスや決済プロセッサーからのリクエストが、ブロックされたイベントに現れる
- 実際のユーザーがいる国からのチャレンジ済みリクエストが大量にある
- ピーク時に、正当なユーザーでレート制限ルールが発動する
正当なユーザーが影響を受けている場合は、レート制限のしきい値を調整するか、特定の IP 範囲向けのスキップルールを追加します。
Security Events Alert 通知を設定すると、セキュリティイベント量が急増したときにアラートを受け取れます。新しい攻撃キャンペーンの早期警告になります。この通知は、Notifications ページの WAF カテゴリにあります。設定手順は、通知を作成する を参照してください。Enterprise のお客様は、より細かいフィルタリング向けに Advanced Security Events Alert を使えます。
ボットトラフィック分析は、ログインエンドポイント上のボットスコア分布を時系列で示します。ログインパスで低スコアのトラフィック(スコア 1〜29)が急増した場合、クレデンシャルスタッフィングキャンペーンの初期シグナルです。
Cloudflare は、ボットスコアと検証状態に基づいて、ボットトラフィックを次のカテゴリに分類します。
- Verified bots: Googlebot、Bingbot、稼働監視サービスなど、Cloudflare が正当だと確認したクローラーとサービスです。Cloudflare は、要件の厳しい 検証済みボットのリスト を維持しています。
- Automated(スコア 1): リクエストが自動化されていると、Cloudflare がかなり確信しています。
- Likely automated(スコア 2-29): ボットである可能性が高いです。このカテゴリと Automated は、スクレイパー、クレデンシャルスタッフィングツール、スパム送信ツールを含む、セキュリティルールの主な対象です。
- Likely human(スコア 30-99): 実際のユーザーからのリクエストに見えます。このトラフィックはチャレンジもブロックもしないでください。
-
Cloudflare ダッシュボードで Security > Analytics > Bot analysis を開きます。
-
上記のボットスコアグループごとのトラフィック分布を確認します。
このガイドでデプロイしたルールがあるにもかかわらず、ログインエンドポイントに自動トラフィックが継続して届く場合は、セキュリティ機能の相互運用 を確認し、ルールが想定どおりの順序で実行されているかを検証したうえで、しきい値の調整を検討してください。
Application Security
- レート制限のベストプラクティス — ログイン保護とクレデンシャルスタッフィング向けの推奨パターン
- カスタムルール — ボットスコアや漏洩認証情報を含むリクエストフィールドを使うルールを作成する
- 漏洩認証情報検出 — 既知のデータ漏洩の認証情報を受信リクエストからスキャンする
- Security Events — セキュリティ製品がアクションしたリクエストを確認する
Cloudflare Bots
- Bot Fight Mode — 既知のボットパターンにチャレンジする無料のボット対策
- Super Bot Fight Mode — アクションを設定できる Pro と Business 向けボット対策
- Bot Management — ML によるスコアリングとカスタムルールを備えた Enterprise 向けボット対策
Turnstile
- Turnstile を始める — ウィジェットを作成し、クライアント側とサーバー側の検証を実装する
- サーバー側検証 — サーバーで Turnstile トークンを検証する
- Turnstile Pre-Clearance — SPA と AJAX のログインフロー向けに訪問者を事前クリアする
SSL/TLS
- Always Use HTTPS — すべての HTTP リクエストを HTTPS へリダイレクトする
- HTTP Strict Transport Security (HSTS) — HSTS ヘッダーでブラウザのダウングレード攻撃を防ぐ