カードテスティングとは、盗んだカードで少額の決済を次々に試し、まだ使えるカードを探すスクリプトです。こうしたスクリプトはたいていページを読み込みません。タグが一度も実行されないため、判定にはブラウザからのシグナルがなく、クラスは通過扱いの unknown になります。シグナルがないことはボットの証拠にはならないので、Bot Protection はそれをボットとは判定しません。そうしたスクリプトが狙うアクションでは、代わりに本物の訪問である証拠、つまりタグのトークンを求めてください。
requireToken の働き
呼び出しに "require_token": true を付けると(SDK の requireToken オプション、Go では RequireToken)、アクションはそのブラウザでタグが取得した有効なトークンがあるときだけ進みます。トークンがなければ、クラスにかかわらず応答は challenge で、token_required が true になります。クラス自体は変わりません。トークンを使うのはフォームの送信で、セッションとパスごとに 1 時間に 1 回です。2 分以内の 3 回までの試行は同じ試行として扱われるため、カードが拒否されて別のカードで払い直す人も通れます。ページの読み込み(GET、HEAD)ではトークンを使わず、SDK はアクションのときだけオプションを送ります。詳しいルールはタグを必要とするアクションをご覧ください。
各アクションが始まるページ、つまりチェックアウト、ログイン、新規登録のページにタグを置いてください。タグ
対象にするルート
- 決済:カードに請求する、または注文を確定する送信と、カードを追加する送信やギフトカードを使う送信。カードテスティングの対象です。
- ログイン:パスワードを確認する送信。リスト型攻撃(クレデンシャルスタッフィング)の対象です。
- 新規登録:アカウントを作成する送信。偽アカウントの対象です。
自社のページから遷移しないルート、たとえば決済代行会社の Webhook、モバイルアプリの API、取引先のサーバーには付けないでください。そこではタグが実行されないため、すべてのリクエストがチャレンジになります。
コードでの設定
各タブは、それぞれのフレームワークのガイドで作る呼び出しにこの設定を加えます。Node と Go は Korzen が配布するクライアントファイルのオプションを使い、それ以外は呼び出しのボディにフィールドを加えます。
Node
// Express, with korzen.js as the Express guide sets it up const guard = protect({ client: korzen, ip: (_get, req) => req.ip, requireToken: true }); app.get("/checkout", guard, showCheckout); // the page: a page load spends no token app.post("/checkout", guard, placeOrder); // the action: it needs the tag's token // Next.js, Hono or any handler of a Web Request export const POST = withKorzen(placeOrder, { client, ip: ipFrom.vercel, requireToken: true });
Go
mux.Handle("POST /checkout", bot.Protect(http.HandlerFunc(placeOrder), korzen.Options{ IP: korzen.RemoteIP, RequireToken: true, // the action needs the tag's token }))
Python
# In decide() of the Django and Flask or FastAPI guide: one more field in the body. json={ # ...the fields the guide sends "path": path, "method": "POST", "require_token": True, # on payment, login and sign-up },
PHP
// In decide() of the PHP or Laravel guide: one more field in the body. 'path' => $path, 'method' => 'POST', 'require_token' => true, // on payment, login and sign-up
Java
// In decide() of the Spring Boot guide: one more field in the body. body.put("path", path); body.put("method", "POST"); body.put("require_token", true); // on payment, login and sign-up
.NET
// In Decide() of the ASP.NET Core guide: one more field in the body. ["path"] = path, ["method"] = "POST", ["require_token"] = true, // on payment, login and sign-up
Ruby
# In decide of the Rails guide: one more field in the body. path: path, method: "POST", require_token: true # on payment, login and sign-up
Cloudflare Worker
# wrangler.toml: the paths whose actions need the tag's token, by commas; # one ending in * is a prefix. [vars] KORZEN_REQUIRE_TOKEN = "/checkout,/login,/signup"
1 つの関数がすべてのアクションの判定を求めている場合は、引数で選べるようにしてください。決済、ログイン、新規登録のハンドラーからは true を、それ以外からは false を渡します。ボディの requireToken のようにフィールド名を間違えると 400 で拒否され、ほかのエラーと同じく訪問者は通されます。最初の応答を確認してください。
まず monitor mode で
アカウントが monitor mode のうちにオンにしてください。どの応答も action は allow のままなので、誰も止められません。トークンなしで来たアクションには、intended_action が challenge、token_required が true の応答が返ります。数日間、次の 2 つの数字を見てください。
- サーバーのログに残る応答のうち、これらのルートで
token_requiredが true の判定。 - セットアップページの連携の状態にある「トークンなし」の割合。ここが高いときは、アクションにつながるページにタグがない、またはタグの実行前にフォームが送信されていることがほとんどです。先にそれを直してください。
残るのは主にスクリプトと、ブラウザでタグが実行されない一部の人です(下記)。その割合を許容できると判断したら、block mode をオンにしてください。monitor mode と block mode
クラスごとのアクション
チェックアウトにはデフォルトの設定が合っています。クラスのアクションとトークンは別のものです。有効なトークンがあればアクションはクラスのとおりになり、なければ少なくとも challenge になります。
| クラス | アクション | チェックアウトでは |
|---|---|---|
| human high | allow | そのまま進める |
| human | allow | そのまま進める |
| unknown | allow | そのまま進める。トークンを必須にしていれば、ページを飛ばしたスクリプトには代わりに challenge が返る |
| bot | challenge | 3-D セキュアやメールでのコード確認など自社の確認、またはチェックアウトページから当社のチャレンジページへ |
| bot high | block | カードが拒否されたときと同じメッセージで断り、スクリプトに何も学ばせない |
セットアップページで bot と bot_high のおとりの応答をオンにすると、SDK がそのアクションに自動で成功のように見える応答を返すため、スクリプトは何も学べません。おとりの応答
決済の後は、決済代行会社から届いた結果をフィードバックとして送ってください。チャージバックや確認された不正はそのブラウザの次の判定を下げ、優良なお客様は上げます。
それで止まる人
ブラウザでタグが実行されない訪問者はトークンを持ちません。タグを止める広告ブロッカーやプライバシー拡張機能、Bot Protection の API ホストを止める DNS フィルター、JavaScript の無効化がその例です。require_token を付けたルートでは、block mode のとき、こうした訪問者はアクションでチャレンジを受けます。当社のチャレンジページは、小さな proof of workと、そのページでのタグの実行を求めます。JavaScript が無効なら通る方法はなく、当社のホストを止める DNS フィルターはこのページも止めます。ほかの手段を用意しない限り、その人は支払えません。
- スクリプトによる損失が、止められる人の損失より大きいルート、つまり決済、ログイン、新規登録だけに付けてください。すべてのルートには付けないでください。
- 上で述べたとおり、block mode をオンにする前に monitor mode で割合を確認してください。
challengeのときは、当社のタグを必要としない手段があれば案内してください。3-D セキュア、メールや電話でのコード確認、サポートへの連絡などです。SDK のonChallengeフックを使うと、リダイレクトの代わりにそれを実行できます。
Bot Protection が遅いときや停止しているときは、トークンの有無にかかわらず、サーバーは訪問者を通します。呼び出しは fail-open です。