profile-website-bot-detection について
対象サイトのボット検出ベンダー、製品、チャレンジを調べるスキルです。ステルスと通常のブラウザを比較し、セキュリティ分析用のレポートを作成します。
主な機能
- 01ボット検出ベンダーと製品の特定
- 02チャレンジとブロックの検出
- 03ホームページとログインページの分析
- 04ステルスと通常ブラウザの比較
- 05JSON レポートとスクリーンショットの生成
活用シーン
- 01サイトのボット検出構成の調査
- 02ブラウザモード別の検出結果の比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kernel/ skills --skill profile-website-bot-detectionインストール後、Claude Code で/profile-website-bot-detectionを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
scripts/.gitignorepackage.jsontest-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:比較結果を解釈する
| シナリオ | ステルス | 通常 | 意味 |
|---|---|---|---|
| ベンダーを検出しない | 0 | 0 | シグナルは観測されていません。サイトにボット検出機能がないと決めつけないでください |
| 同じベンダー、ブロックなし | N | N | ボット検出機能があり、両方とも通過しています |
| 通常はブロックされ、ステルスは通過 | ブロック 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> で削除してください。
結果の解釈
分析では、ベンダーとその特定の製品を検出します。
| ベンダー | 検出された製品 |
|---|---|
| Akamai | Bot Manager、Bot Manager Premier、mPulse RUM、Sensor Script、Edge DNS |
| Cloudflare | Bot Management、Turnstile、Challenge Platform、JS Challenge、Managed Challenge |
| DataDome | Interstitial Challenge、Slider Challenge、Device Check、Picasso Fingerprint |
| HUMAN/PerimeterX | Bot Defender、Sensor SDK、Press & Hold Challenge |
| Imperva/Incapsula | Advanced Bot Protection (utmvc)、Advanced Bot Protection (reese84)、WAF |
| Kasada | IPS (Initial Page Security)、FP (Fingerprint Endpoint)、Telemetry、POW Challenge |
| reCAPTCHA v2、reCAPTCHA v3、reCAPTCHA Enterprise | |
| hCaptcha | Widget、Enterprise |
| FingerprintJS | Fingerprint Pro、BotD |
| Arkose Labs | FunCaptcha |
検出方法:
- ベンダーのスクリプトとエンドポイントの 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)
分析対象ページ
スクリプトは以下を自動的に分析します。
- ホームページ - 初回ページ読み込みとボット検出スクリプト
- ログインページ - リンク検出または一般的なパス(
/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:真偽値 - いずれかのページがブロックされた場合は truevendorNames:検出されたベンダー名の配列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フィンガープリントリクエスト