flawopen.com/SSRF/Node.js fetch() und SSRF
Verhindert Node.js fetch() Server-Side Request Forgery (SSRF)?
Nein. Serverseitiges fetch() sendet Anfragen vom Server. Wählt der Aufrufer das Ziel, kann er Systeme ansteuern, die der Server, nicht aber der Aufrufer erreicht. Wie ein vertrauenswürdiger Kurier, der ein Paket ohne Adressprüfung zustellt. Das Risiko hängt von Netzwerk, Identität, URL-Regeln und Redirect-Verhalten ab.
providerId zu einem von der Anwendung konfigurierten Ursprung. Vermeidet beliebige URLs.Ursache: Der Server vertraut einem vom Aufrufer gewählten Ziel
Node.js fetch() ist ein allgemeiner HTTP-Client, keine SSRF-Richtlinie. Er entscheidet nicht, welche Netze erreichbar sein sollen; Browser-CORS setzt serverseitig keine Zielgrenze. Auch URL-Parsing reicht nicht: Ein erlaubter Host kann auf eine verbotene Adresse zeigen, und eine Antwort kann zu einem anderen Host umleiten. Funktionen, die Nutzer-Avatare, Webhooks, Dokumente oder Vorschauen abrufen, können das Risiko eröffnen.
So überschreitet die Anfrage die Vertrauensgrenze
Der Aufrufer beeinflusst eine URL
Ein Endpunkt akzeptiert eine vollständige URL oder genügend Angaben, um sie etwa für eine Bildvorschau zu bauen.
Der Server sendet die Anfrage
Der HTTP-Client nutzt Netzwerkpfad, DNS, Proxy und Identität des Serverprozesses.
Ein Redirect ändert das Ziel
Fetch folgt standardmäßig Redirects. Ein anfangs erlaubtes Ziel kann per Location auf einen gesperrten Host verweisen.
Die Antwort legt erreichbare Daten offen
Wenn Richtlinie und Netzwerk es zulassen, können interne Dienste oder Cloud-Metadaten erreichbar sein. Das hängt von der Umgebung ab.
Unsichere und sicherere Node.js-Muster
// Keine beliebige vom Aufrufer gelieferte URL abrufen.
const response = await fetch(userProvidedUrl);
// Der Aufrufer wählt einen Schlüssel, kein Netzwerkziel.
const destinations = new Map([
["status", new URL("https://status.example/")],
["docs", new URL("https://docs.example/")],
]);
const target = destinations.get(providerId);
if (!target) throw new Error("Unknown provider");
const response = await fetch(target, {
redirect: "error",
signal: AbortSignal.timeout(3000),
});
if (!response.ok) throw new Error("Upstream request failed");
Wenn Benutzer URLs übermitteln müssen
Bevorzugen Sie eine Provider-ID, die auf ein festes Ziel verweist. Wenn beliebige öffentliche URLs nötig sind, erlauben Sie nur erforderliche Schemen und Ports; verwerfen Sie User-Info, Loopback, private und link-lokale sowie andere verbotene IPv4-/IPv6-Ziele. Prüfen Sie alle DNS-Adressen und sorgen Sie dafür, dass die Verbindung eine geprüfte Adresse verwendet, ohne ungeprüfte zweite Auflösung. Deaktivieren Sie Redirects oder prüfen Sie jeden Sprung. Erzwingen Sie zusätzlich Egress-Regeln, einschließlich Sperren für Metadaten wie 169.254.169.254 und den aktivierten IPv6-Endpunkt. Begrenzen Sie Laufzeit, Antwortgröße und Parallelität; leiten Sie keine internen Zugangsdaten weiter.
SSRF-Prüfliste
- ✓Ersetzen Sie beliebige URLs möglichst durch eine feste Zuordnung eines validierten Providerschlüssels zu einem anwendungseigenen Ziel.
- ✓Erlauben Sie nur
https:und erwartete Ports; verwerfen Sie URL-Zugangsdaten, unerwartete Hosts, IP-Literale und gesperrte Bereiche. - ✓Deaktivieren Sie Redirects mit
redirect: "error"; prüfen Sie andernfalls jedes Ziel vor der Verbindung. - ✓Prüfen Sie alle A-/AAAA-Antworten und binden Sie die Verbindung an eine geprüfte Adresse, während die Hostnamenprüfung erhalten bleibt. Berücksichtigen Sie Wiederholungen und Proxies.
- ✓Sperren Sie Loopback, private, link-lokale und Metadatennetze einschließlich IPv6 per Egress-Firewall oder Proxy. Anwendungskontrollen allein reichen nicht.
- ✓Begrenzen Sie Zeit, Antwortbytes und Parallelität. Leiten Sie keine Cookies, Autorisierungsheader oder Cloud-Zugangsdaten weiter.
- ✓Erzwingen Sie bei AWS IMDSv2 und beschränken Sie Metadatenzugriffe als zusätzliche Schutzschicht; URL- und Egress-Kontrollen bleiben nötig.
Häufige Fragen
Nein. Redirects, IPv4-/IPv6-Varianten, DNS-Rebinding, Proxies und Rennen zwischen Auflösung und Verbindung umgehen einfache Prüfungen. Nutzen Sie eine Zielliste. Bei beliebigen Zielen müssen Sie jede Adresse prüfen und die Verbindung daran binden; setzen Sie dieselbe Regel am Netzwerkausgang durch.
Nein. IMDSv2 erfordert ein Token und reduziert einige Risiken, aber SSRF kann je nach Konfiguration andere interne Dienste oder Metadaten erreichen. Ziel- und Egress-Kontrollen bleiben nötig.
Primärquellen
- OWASP — Schutz vor SSRF
- Node.js — Globale fetch-API
- WHATWG-Fetch-Standard — Redirect-Modus
- AWS — Optionen des EC2-Metadatendienstes
- CWE-918 — Server-Side Request Forgery