- ホーム
- クライアントサイド防御
- Demo
- フェーズ 3 — 軽減
フェーズ 3 — 軽減
フェーズ 3 では CSD 軽減の前後の証拠を作成します。まず軽減なしで攻撃を再実行してベースラインを確立し、軽減を適用したうえで同じ攻撃を再実行することで、CSD がネットワーク呼び出しをブロックすることを証明します。先に進む前に、フェーズ 2 が完了していること(すべての DET チェックが PASS になっていること)が必要です。
ステップ 1: アクティブな軽減がないことを確認する(ベースライン)
Section titled “ステップ 1: アクティブな軽減がないことを確認する(ベースライン)”「前」のスナップショットを取得する前に、環境がクリーンであること(軽減がアクティブでないこと)を確認します。これにより、CSD ブロックなしでベースライン攻撃が実行されます。
軽減済みドメイン数の確認
Section titled “軽減済みドメイン数の確認”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq '{count: (.items | length)}'カウントが 0 でない場合、前の実行から軽減が残っています。先に進む前に、それぞれを削除してください:
# 軽減済みドメインを削除する(ドメイン名ごとに繰り返す)curl -s -X DELETE \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains/<domain-name>" \ | jq .<domain-name> は、ドメインを軽減した際に使用した metadata.name(例: cdn.jsdelivr.net、esm.sh、unpkg.com、ga.jspm.io、httpbin.org、jsonplaceholder.typicode.com)に置き換えてください。httpbin.org のクリーンアップ後にアイテムが残る場合は、www.httpbin.org の削除も試してください。前の実行でそちらをメタデータ名として使用している可能性があります。
フェーズ 2 の検出結果が存在することを確認する
Section titled “フェーズ 2 の検出結果が存在することを確認する”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'| チェック | 期待値 | ステータス |
|---|---|---|
| 軽減済みドメイン数 | 0(クリーンなベースライン) | 0 なら PASS、> 0 ならクリーンアップが必要 |
| 検出済みドメイン数 | > 0(フェーズ 2 の検出結果が存在) | > 0 なら PASS |
| 流出ドメインの存在 | www.httpbin.org、jsonplaceholder.typicode.com | 少なくとも 1 件あれば PASS |
ステップ 2: 攻撃を実行する — 軽減前
Section titled “ステップ 2: 攻撃を実行する — 軽減前”軽減がアクティブでない状態で、組み合わせシミュレーションを再実行し、新鮮なベースラインを取得します。これが**「前」のスナップショット**であり、CSD 軽減が適用されていない場合に攻撃が成功することの証明です。
AI 自動実行
Section titled “AI 自動実行”ブラウザ自動化ツールを持つ AI アシスタントは、フェーズ 2 と同じ initScript(ネイティブ fetch を保存する)を使用して攻撃シミュレーションをプログラム的に実行します:
- initScript を使用してナビゲート — まずクリーンなドキュメントコンテキストを確保するために
about:blankにナビゲートし(前のナビゲーションからの古い initScript を回避)、次にフェーズ 2 の initScript(フェーズ 2 — AI 自動実行 の逐語的なコード)を使用してhttp://$F5XC_DOMAINNAME/#/loginにnavigate_pageします。この initScript はネイティブのsetInterval、clearInterval、fetch、console.logを保存します。軽減がアクティブでないため、ネイティブfetchの参照はここでは正しいものです - ウェルカムバナーを閉じる —
Escapeキーでpress_keyしてウェルカムバナーを閉じます。再訪問時はバナーが表示されない場合があります(Cookie が永続化されています)。Cookie 同意ダイアログは Escape キーで自動的に閉じられます - 完了を待つ — すべての CDN スクリプトのロード/エラーコールバックと fetch Promise の解決が完了するまで 10 秒待ちます
- 証拠を取得する —
list_console_messagesで[CSD Demo] Simulation completeと CDN ロード結果を確認します;list_network_requestsをscriptおよびfetchタイプでフィルタリングして HTTP ステータスコード(成功の場合は200/201)を確認します
ブラウザ自動化ツールを持たないオペレーターは、フェーズ 2 — ステップ 8: 攻撃シミュレーションと同じ手順でシミュレーションを手動で実行します:
http://xF5XC_DOMAINNAMEx/#/loginにナビゲートします- メールとパスワードフィールドにダミーの認証情報を入力します(送信しないでください)
- DevTools を開きます — F12 を押して Console タブに切り替えます
- トリガー検出の組み合わせ検出スクリプトを貼り付けて実行します
- コンソール出力を観察します — すべての CDN スクリプトが読み込まれ、流出呼び出しが
200/201レスポンスで成功するはずです
証拠 — 軽減前
Section titled “証拠 — 軽減前”| チェック | 期待値(軽減前) | ステータス |
|---|---|---|
| CDN スクリプト注入 | 4 つのスクリプトタグがすべて読み込まれる — [Supply Chain] Loaded from メッセージが表示され、ネットワークタブに 200 が表示される | PASS |
www.httpbin.org への流出 fetch | ネットワークタブに 200 — データが送信された | PASS |
| jsonplaceholder.typicode.com への流出 fetch | ネットワークタブに 201 — データが送信された | PASS |
| コンソール出力 | [CSD Demo] Simulation complete | PASS |
ステップ 3: 軽減を適用する
Section titled “ステップ 3: 軽減を適用する”検出されたドメインごとに、軽減済みドメインエンドポイントに POST します。フェーズ 2 のシミュレーションからの主要なターゲットは、4 つの CDN 注入ドメインと検出されたデータ流出ドメインです。
主要な軽減ターゲット(組み合わせシミュレーションスクリプトより):
| ドメイン | 役割 |
|---|---|
cdn.jsdelivr.net | CDN スクリプト注入 |
esm.sh | CDN スクリプト注入 |
unpkg.com | CDN スクリプト注入 |
ga.jspm.io | CDN スクリプト注入 |
www.httpbin.org | データ流出エンドポイント |
jsonplaceholder.typicode.com | データ流出エンドポイント |
ドメインを軽減する(ドメインごとに 1 回実行):
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "name": "cdn.jsdelivr.net", "namespace": "xF5XC_NAMESPACEx" }, "spec": { "mitigated_domain": "cdn.jsdelivr.net" } }' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .各ドメインに対して繰り返します:
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"esm.sh","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"esm.sh"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# unpkg.comcurl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"unpkg.com","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"unpkg.com"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# ga.jspm.iocurl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"ga.jspm.io","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"ga.jspm.io"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# httpbin.org — mitigated_domain には www.httpbin.org を使用する(以下の注意を参照)curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"httpbin.org","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"www.httpbin.org"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .
# jsonplaceholder.typicode.comcurl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{"metadata":{"name":"jsonplaceholder.typicode.com","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"jsonplaceholder.typicode.com"}}' \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq .200 レスポンスは作成された軽減済みドメインオブジェクトを返します。409 レスポンスはドメインがすでに軽減リストに含まれていることを意味します。これは成功条件です。
ステップ 4: 軽減が適用されたことを確認する
Section titled “ステップ 4: 軽減が適用されたことを確認する”すべての軽減済みドメインを一覧表示し、カウントが送信したドメイン数と一致することを確認します:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq '{count: (.items | length)}'| チェック | 期待値 | ステータス |
|---|---|---|
| 軽減済みドメイン数 | 6(POST 数と一致) | カウントが一致すれば PASS |
ステップ 3 のすべての POST が 200 または 409 を返した | 各ドメインが受け入れられた | PASS |
カウントが期待値より少ない場合は、ステップ 3 から不足しているドメインの POST コマンドを再実行してください。
ステップ 5: 攻撃を実行する — 軽減後
Section titled “ステップ 5: 攻撃を実行する — 軽減後”「後」のスナップショットを取得するために、まったく同じ組み合わせシミュレーションを再実行します。シミュレーションスクリプトは同一です。変わったのは CSD の軽減状態だけです。軽減済みドメインからのスクリプト読み込みは、CSD JavaScript によってブロックされるようになっています(<script> タグの src が空文字列にクリアされます)。
AI 自動実行
Section titled “AI 自動実行”ブラウザ自動化ツールを持つ AI アシスタントは、フェーズ 2 と同じ initScript(フェーズ 2 — AI 自動実行 の逐語的なコード)を使用して攻撃シミュレーションをプログラム的に再実行します。initScript はネイティブ fetch を保存して zone.js エラーを回避します。CSD は fetch() 呼び出しをインターセプトしないため、これは CSD 軽減に影響しません。
- initScript を使用してナビゲート — クリーンなブラウザコンテキストのために
isolatedContextを指定したnew_pageを使用し(ステップ 2 の古い initScript を回避)、about:blankにナビゲートし、次にフェーズ 2 の initScript を使用してログインページにナビゲートします - ウェルカムバナーを閉じる —
Escapeキーでpress_keyします - 完了を待つ — すべての非同期コールバックが完了するまで 10 秒待ちます
- 証拠を取得する —
list_console_messagesで[CSD Demo] Simulation completeを確認します;list_network_requestsをscriptおよびfetchタイプでフィルタリングして、CDN スクリプトの読み込みが存在しないこと(CSD がスクリプト src をクリアした)を観察し、流出ドメインへの fetch 呼び出しは引き続き正常に完了することを確認します
ブラウザ自動化ツールを持たないオペレーターは、フェーズ 2 — ステップ 8: 攻撃シミュレーションと同じ手順でシミュレーションを手動で再実行します:
http://xF5XC_DOMAINNAMEx/#/loginにナビゲートします- メールとパスワードフィールドにダミーの認証情報を入力します(送信しないでください)
- DevTools を開きます — F12 を押して Console タブに切り替えます
- トリガー検出の組み合わせ検出スクリプトを貼り付けて実行します
- コンソールとネットワーク出力を観察します — 軽減済みドメインの CDN スクリプトの
onloadおよびonerrorコールバックは発火しません(CSD がスクリプトsrcを空文字列にクリアし、ネットワークリクエスト自体を防いだためです)。流出ドメイン(www.httpbin.org、jsonplaceholder.typicode.com)への fetch 呼び出しは200/201で引き続き完了します — CSD 軽減はスクリプトの読み込みをブロックし、fetch/XHR 呼び出しはブロックしません
証拠 — 軽減後
Section titled “証拠 — 軽減後”| チェック | 期待値(軽減後) | ステータス |
|---|---|---|
| CDN スクリプトの読み込み | ブロック済み — スクリプトがネットワークタブに表示されない(CSD が src を空文字列にクリアした) | PASS |
| CDN スクリプトコールバック | 軽減済みドメインの onload も onerror も発火しない | PASS |
www.httpbin.org への流出 fetch | 200 — fetch は引き続き完了する(CSD は fetch をインターセプトしない) | INFO |
| jsonplaceholder.typicode.com への流出 fetch | 201 — fetch は引き続き完了する(CSD は fetch をインターセプトしない) | INFO |
| コンソール出力 | [CSD Demo] Simulation complete | PASS |
ステップ 6: 前後の比較
Section titled “ステップ 6: 前後の比較”これがデモのクライマックスです。同じページで、同じスクリプトを使用して、まったく同じ攻撃を実行したにもかかわらず、まったく異なる結果になることを並べて示す証拠です。
| シグナル | 軽減前(ステップ 2) | 軽減後(ステップ 5) |
|---|---|---|
| CDN スクリプトの読み込み | 200 — 4 つの CDN スクリプトがすべて正常に読み込まれる | ブロック済み — スクリプトがネットワークタブに表示されない(CSD が src を空文字列にクリアした) |
CDN onload コールバック | [Supply Chain] Loaded from メッセージが表示される | コールバックは発火しない(ネットワークリクエストが行われなかった) |
www.httpbin.org への流出 | 200 — データが流出した | 200 — fetch は引き続き完了する(CSD は fetch をインターセプトしない) |
| jsonplaceholder.typicode.com への流出 | 201 — データが流出した | 201 — fetch は引き続き完了する(CSD は fetch をインターセプトしない) |
| CSD 軽減済みドメイン API | 0 件軽減済み | 6 件軽減済み |
バックエンドデータでの軽減確認
Section titled “バックエンドデータでの軽減確認”/detected_domains を 60 秒ごとに最大 10 回(10 分)クエリします。クエリが返ってきた時点、または最大 10 分後に比較表に進んでください。これらのチェックは情報提供目的であり、フェーズ 4 のゲートにはなりません。
軽減後の検出済みドメインの確認:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'軽減済みステータスのスクリプト確認:
NOW=$(date +%s)START=$(( NOW - 86400 ))curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{\"startTime\": \"$START\", \"endTime\": \"$NOW\"}" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \ | jq '{total: (.scripts | length), scripts: [.scripts[]? | {script_name: .script_name, risk_level: .risk_level}]}'フェーズ 3 証拠サマリー
Section titled “フェーズ 3 証拠サマリー”| チェック | 期待値 | ステータス |
|---|---|---|
| ベースラインクリーン(ステップ 1) | 開始時に軽減済みドメインが 0 件 | PASS / FAIL |
| 前 — 攻撃が成功する(ステップ 2) | スクリプトが読み込まれ、流出が 200/201 を返す | PASS / FAIL |
| 軽減が適用された(ステップ 3) | 6 つのドメインすべてが POST で受け入れられた(200 または 409) | PASS / FAIL |
| 軽減済み数が確認された(ステップ 4) | リストに 6 件 | PASS / FAIL |
| 後 — スクリプトの読み込みがブロックされた(ステップ 5) | CDN スクリプトがネットワークタブに表示されず、fetch 呼び出しは引き続き完了する | PASS / FAIL |
| 前後比較(ステップ 6) | ステップ 2 とステップ 5 の証拠に明確な違いがある | PASS / FAIL |
フェーズ 3 完了。 すべてのデプロイメントオブジェクトを削除する準備ができたら、フェーズ 4 — ティアダウンに進んでください。