mcpField
P
profile-website-bot-detection

profile-website-bot-detection

github.com/kernelセキュリティ13384 回インストール2 週間前に更新
リポジトリ

profile-website-bot-detection について

対象サイトのボット検出ベンダー、製品、チャレンジを調べるスキルです。ステルスと通常のブラウザを比較し、セキュリティ分析用のレポートを作成します。

主な機能

  1. 01ボット検出ベンダーと製品の特定
  2. 02チャレンジとブロックの検出
  3. 03ホームページとログインページの分析
  4. 04ステルスと通常ブラウザの比較
  5. 05JSON レポートとスクリーンショットの生成

活用シーン

  1. 01サイトのボット検出構成の調査
  2. 02ブラウザモード別の検出結果の比較

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kernel/skills --skill profile-website-bot-detection

インストール後、Claude Code で/profile-website-bot-detectionを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

scripts/
.gitignore
package.json
test-kernel-bot-detection.ts

詳細

ボット検出ベンダー向けのウェブサイトプロファイリング

対象のウェブサイトを分析し、ボット検出ベンダー、その具体的な製品、チャレンジの種類を特定します。ステルスモードと非ステルスモードのブラウザー間で比較分析できます。

前提条件

  • Kernel CLI がインストールされ、認証済みであること
  • Bash、Node.js 22 以降、および jq がインストールされていること
  • 分析スクリプト用に KERNEL_API_KEY がエクスポートされていること。決して表示したり、チャットに貼り付けるようユーザーに求めたりしないでください

比較ワークフロー(推奨)

ネットワーク経路を同じ条件に保ちながら、ステルスブラウザーと非ステルスブラウザーでボット検出の動作を比較します。クリーンアップ用のトラップが有効な状態を保つため、ステップ 1~7 は同じ Bash プロセスで実行してください。ステップ 2 を単独の非対話型シェルとして実行しないでください。そのシェルが終了すると、EXIT トラップによってセッションが削除されます。

ステップ 1:分析ツールを準備する

課金対象のブラウザーセッションを作成する前に、依存関係をインストールします。

cd scripts
npm install  # first run only
export TARGET_URL='https://example.com'
test -n "${KERNEL_API_KEY:-}" || { echo "KERNEL_API_KEY is not set" >&2; exit 1; }
ステップ 2:両方のブラウザータイプを作成し、クリーンアップを設定する

JSON 出力を使用して、正確なセッション ID を取得します。2 つ目のセッションの作成に失敗した場合や、その後の分析が失敗した場合は、EXIT トラップが最初のセッションをクリーンアップします。

set -euo pipefail
STEALTH_ID=
NORMAL_ID=

cleanup() {
  local ids=()
  [[ -n "${STEALTH_ID:-}" ]] && ids+=("$STEALTH_ID")
  [[ -n "${NORMAL_ID:-}" ]] && ids+=("$NORMAL_ID")
  if ((${#ids[@]})); then
    kernel browsers delete "${ids[@]}" || true
  fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

STEALTH_ID=$(kernel browsers create --stealth --viewport 1920x1080@25 --timeout 300 --output json | jq -er '.session_id')
NORMAL_ID=$(kernel browsers create --viewport 1920x1080@25 --timeout 300 --output json | jq -er '.session_id')

# Isolate browser stealth behavior: route the stealth session directly, like the normal session.
kernel browsers update "$STEALTH_ID" --disable-default-proxy >/dev/null

ステルスセッションは、変更しない場合、Kernel のデフォルトのステルスプロキシを使用します。一方、通常のセッションは直接接続します。更新を行わない場合、測定されるのはステルス単独ではなく、ステルス+プロキシと通常+直接接続の違いです。--disable-default-proxy はステルスセッションにのみ適用してください。非ステルスセッションに指定すると、API が拒否します。

ページに移動する前に、ネットワーク設計を 1 つ選択してください。

  • ブラウザーモードの比較(推奨): 上記の更新を維持し、両方のセッションが直接接続するようにします。
  • プラットフォームのデフォルト設定との比較: 更新を省略し、ステルスの結果を stealth + default proxy として報告します。差異をステルスだけに起因するものとしないでください。
  • 明示的なプロキシとの比較: 必要に応じて kernel proxies check "$PROXY_ID" --url https://example.com --output json で設定済みプロキシを検証し、両方の作成コマンドに --proxy-id "$PROXY_ID" を追加して、更新を省略します。プロキシ設定は統一されますが、プロバイダーによるローテーションで出口 IP が異なる場合があります。
ステップ 3:両方のブラウザーで分析を実行する
KERNEL_BROWSER_ID="$STEALTH_ID" TARGET_URL="$TARGET_URL" BROWSER_MODE=stealth npm run analyze
KERNEL_BROWSER_ID="$NORMAL_ID" TARGET_URL="$TARGET_URL" BROWSER_MODE=normal npm run analyze

各分析の実行では、レポートを書き込んだ後にローカルの CDP クライアントを切断します。比較とクリーンアップのため、Kernel セッションはアクティブなままです。

ステップ 4:結果を比較する

複数の JSON ドキュメントを連結せず、各モードで最新のレポートを比較します。

# Derive the same hostname folder used by the analyzer (e.g., chase.com -> chase-com).
HOST=$(node -e 'const host = new URL(process.env.TARGET_URL).hostname; console.log(host.replace(/^www\./, "").replace(/\./g, "-"))')
latest_report() {
  local reports=("$1"/report-*.json)
  [[ -e "${reports[0]}" ]] || return 1
  printf '%s\n' "${reports[@]}" | sort | tail -n 1
}
STEALTH_REPORT=$(latest_report "output/$HOST/stealth")
NORMAL_REPORT=$(latest_report "output/$HOST/normal")

echo "=== STEALTH VERDICT ===" && jq '.summary.verdict' "$STEALTH_REPORT"
echo "=== NORMAL VERDICT ===" && jq '.summary.verdict' "$NORMAL_REPORT"

echo "=== STEALTH BLOCKED ===" && jq '.summary | {isBlocked, blockedPages, blockedVendors}' "$STEALTH_REPORT"
echo "=== NORMAL BLOCKED ===" && jq '.summary | {isBlocked, blockedPages, blockedVendors}' "$NORMAL_REPORT"

echo "=== STEALTH VENDORS ===" && jq '.summary.vendorNames' "$STEALTH_REPORT"
echo "=== NORMAL VENDORS ===" && jq '.summary.vendorNames' "$NORMAL_REPORT"
ステップ 5:比較結果を解釈する
シナリオステルス通常意味
ベンダーを検出しない00シグナルは観測されていません。サイトにボット検出機能がないと決めつけないでください
同じベンダー、ブロックなしNNボット検出機能があり、両方とも通過しています
通常はブロックされ、ステルスは通過ブロック 0 件ブロックネットワーク条件を統一した場合、ステルスが有効です
両方ともブロックブロックブロックテストした両方の設定がブロックされています
チャレンジの種類が異なる軽度厳重ネットワーク条件を統一した場合、ステルスによって疑いが軽減されている可能性があります
ステップ 6:概要を提示する

比較分析の実行後、ネットワーク設計を明記します。両方のセッションで同じネットワーク種別を使用した場合にのみ、ステルスの有効性を主張してください。

概要レポートのテンプレート:

## Bot Detection Comparative Analysis: [TARGET_URL]

### Verdict
- **Network Design**: [both direct / same explicit proxy config / platform defaults]
- **Stealth Browser**: [verdict from summary.verdict]
- **Normal Browser**: [verdict from summary.verdict]
- **Stealth Effectiveness**: [Effective/Ineffective/Inconclusive; use Inconclusive for mixed network paths]

### Block Status
| Browser | Blocked | Block Type | Evidence |
|---------|---------|------------|----------|
| Stealth | [Yes/No] | [blockType or N/A] | [first evidence item] |
| Normal  | [Yes/No] | [blockType or N/A] | [first evidence item] |

### Detected Vendors
| Vendor | Stealth | Normal | Products |
|--------|---------|--------|----------|
| [vendor] | ✓/✗ | ✓/✗ | [product list] |

### Analysis
- [Explain what the results mean]
- [Note any differences between stealth and normal]
- [Recommend next steps if blocked]

### Key Findings
1. [Finding 1]
2. [Finding 2]
3. [Finding 3]

JSON レポートの情報を使って、次の項目をテンプレートに入力します。

  • summary.verdict - 最終的な判定文字列
  • summary.isBlocked - ブラウザーがブロックされたかどうか
  • summary.blockedPages - ブロックされたページの詳細
  • summary.vendorNames - 検出されたベンダーの一覧
  • vendorDetections - ベンダーおよび製品に関する詳細情報
ステップ 7:クリーンアップする

レポートを収集したら、両方のセッションをすぐに削除します。browsers delete は非対話型で、複数の ID を指定できます。-y フラグはありません。

cleanup
trap - EXIT INT TERM

シェルが中断された場合や、変数が失われた場合は、kernel browsers list で作成したセッションを確認し、各セッションを kernel browsers delete <session-id> で削除してください。


結果の解釈

分析では、ベンダーとその特定の製品を検出します。

ベンダー検出された製品
AkamaiBot Manager、Bot Manager Premier、mPulse RUM、Sensor Script、Edge DNS
CloudflareBot Management、Turnstile、Challenge Platform、JS Challenge、Managed Challenge
DataDomeInterstitial Challenge、Slider Challenge、Device Check、Picasso Fingerprint
HUMAN/PerimeterXBot Defender、Sensor SDK、Press & Hold Challenge
Imperva/IncapsulaAdvanced Bot Protection (utmvc)、Advanced Bot Protection (reese84)、WAF
KasadaIPS (Initial Page Security)、FP (Fingerprint Endpoint)、Telemetry、POW Challenge
GooglereCAPTCHA v2、reCAPTCHA v3、reCAPTCHA Enterprise
hCaptchaWidget、Enterprise
FingerprintJSFingerprint Pro、BotD
Arkose LabsFunCaptcha

検出方法:

  • ベンダーのスクリプトとエンドポイントの URL パターン照合
  • Cookie の分析(例:_abck、__cf_bm、datadome、_px*)
  • ヘッダーの検出(例:cf-ray、x-kpsdk-*、x-d-token)
  • レスポンスのステータスコードに基づくチャレンジの検出

ベンダー固有のチェック:

  • DataDome:ハード IP ブロックの検出(dd.t === 'bv')
  • Akamai:Cookie の有効性チェック(~0~ インジケーター)
  • Kasada:フロータイプの検出(IPS と FP)
分析対象ページ

スクリプトは以下を自動的に分析します。

  1. ホームページ - 初回ページ読み込みとボット検出スクリプト
  2. ログインページ - リンク検出または一般的なパス(/login、/signin など)を通じて自動検出

ログインページでは、クレデンシャルスタッフィング対策のため、より積極的なボット検出が行われることがよくあります。

出力ファイル

結果は、対象のホスト名ごとに scripts/output/<hostname>/<mode>/ に整理されます。

  • report-<timestamp>.json - ベンダー検出結果を含む完全な JSON レポート
  • screenshot-homepage-<timestamp>.png - ホームページのスクリーンショット
  • screenshot-login-<timestamp>.png - ログインページのスクリーンショット(見つかった場合)

chase.com の比較テストにおける構成例:

output/chase-com/
├── stealth/
│   ├── report-*.json
│   ├── screenshot-homepage-*.png
│   └── screenshot-login-*.png
└── normal/
    ├── report-*.json
    ├── screenshot-homepage-*.png
    └── screenshot-login-*.png

JSON レポートには以下が含まれます。

  • summary:判定結果、ブロック状態、ベンダー名にすばやくアクセスできます
    • verdict:人が読み取れる形式の結果(例:「ブロック - ホームページ(エラーページ)」)
    • isBlocked:真偽値 - いずれかのページがブロックされた場合は true
    • vendorNames:検出されたベンダー名の配列
    • blockedPages:証拠を含む、ブロックされたページの詳細
  • vendorDetections:製品、URL、Cookie、ヘッダーを含む、検出されたベンダーのマップ
  • blockDetections:各ページのブロックに関する詳細な分析
  • vendorScriptsDetected:検出されたベンダースクリプトの URL(ディスクには保存されません)
  • networkRequests/networkResponses:ベンダーとの照合結果を含むすべてのリクエスト
  • cookies:ベンダー情報が付与されたすべての Cookie

ベンダー固有の検出に関する注意事項

Akamai
  • Cookie:_abck(コア検証)、bm_sz、bm_sv
  • _abck の値に ~0~ が含まれる Cookie = 有効なセッション
Cloudflare
  • Cookie:__cf_bm、cf_clearance
  • チャレンジ:/cdn-cgi/challenge-platform/
  • Turnstile:challenges.cloudflare.com/turnstile
DataDome
  • Cookie:datadome
  • dd.t === 'bv' = ハード IP ブロック(IP の変更が必要です。CAPTCHA を解いても解決しません)
HUMAN/PerimeterX
  • Cookie:_px2、_px3、_pxhd
  • Press & Hold チャレンジでは、動作のシミュレーションが必要です
Imperva/Incapsula
  • utmvc:/_Incapsula_Resource 経由のスクリプト
  • reese84:Cookie または x-d-token ヘッダー
Kasada
  • ヘッダー:x-kpsdk-ct、x-kpsdk-cd
  • フロー 1(IPS):初回ページ読み込み時に 429 が返されます。最初に ips.js を解決する必要があります
  • フロー 2(FP):バックグラウンドでの /fp フィンガープリントリクエスト

コメント