Skip to main content

Server-Side Request Forgery in Node.js-Anwendungen verhindern

Artikel von

David Ekete

blog feature multithreading

20. Februar 2024

0 Min. Lesezeit
How to prevent SSRF Attacks in Node.js

Server-Side Request Forgery (SSRF) ist eine weitverbreitete Sicherheitslücke, die sich unbemerkt in jeder Node.js-Anwendung einschleichen kann. Sie stellt eine erhebliche Bedrohung dar, da Angreifer einen Server dazu bringen können, unbeabsichtigte Anfragen an interne und externe Ressourcen zu senden.

In diesem Artikel erfahren Sie mehr über SSRF, die potenziellen Risiken und Strategien zur Abwehr von SSRF in Node.js-Anwendungen.

Besonders empfehlenswert: Absolvieren Sie die interaktive Lektion zu Server-Side Request Forgery auf Snyk Learn.

Was ist SSRF?

SSRF liegt vor, wenn ein Angreifer die von einem Webanwendungsserver gesendeten Anfragen durch Manipulation von Eingaben oder URLs ausnutzt.

Bei der Eingabemanipulation werden Daten, häufig von Nutzern erstellte, unbefugt verändert, um Sicherheitslücken in einer Anwendung auszunutzen. Im Gegensatz dazu werden bei URL-Verwechslungsangriffen URLs so verändert, dass ein System zu unbeabsichtigten Aktionen verleitet wird, etwa zum Zugriff auf nicht autorisierte Ressourcen oder zum Senden unerlaubter Anfragen.

Unter dem Einfluss des Angreifers sendet der Server Anfragen an die manipulierten URLs. Dabei sieht es so aus, als wären die Anfragen vom Server selbst ausgegangen, wodurch typische Sicherheitsmaßnahmen umgangen werden. Ein erfolgreicher SSRF-Angriff kann einem Angreifer Zugriff auf interne Ressourcen, Datenbanken und Dateien verschaffen und so sensible Daten wie Zugangsdaten offenlegen.

Bei einem der bekanntesten SSRF-Vorfälle nutzte beispielsweise ein ehemaliger Softwareentwickler bei Amazon eine SSRF-Sicherheitslücke aus. Dadurch wurden 140.000 Sozialversicherungsnummern, 80.000 Bankkontonummern und 1 Million Sozialversicherungsnummern offengelegt. Der Datenverstoß betraf 106 Millionen Menschen und verursachte einen Schaden von 250 Millionen US-Dollar.

Ein einfaches Beispiel für einen SSRF-Angriff

Sehen wir uns ein konkretes Beispiel an, um SSRF-Sicherheitslücken besser zu verstehen. Stellen Sie sich vor, Sie arbeiten an einer Webanwendung, über die Nutzer eine URL eingeben, ein Bild von dieser URL abrufen und es sich anzeigen lassen können.

Wenn Sie die Beispiele nachvollziehen möchten, klonen Sie dieses GitHub-Repository. Es enthält den Quellcode für die Webanwendung. Die Anwendung nutzt Express, ein Node.js-Framework, das die Entwicklung von Webdiensten vereinfacht. Außerdem kommt Axios zum Einsatz, eine HTTP-Bibliothek, mit der Sie Anfragen von Node.js aus senden können.

Führen Sie den folgenden Befehl aus, um das Repository mit Git zu klonen:

git clone https://github.com/davidekete/ssrf.git

Hinweis: Git muss auf Ihrem System installiert sein, damit Sie diesen Befehl ausführen können.

Führen Sie nach dem Klonen des GitHub-Repositorys den folgenden Befehl aus, um die Abhängigkeiten zu installieren:

npm install

Hinweis: Node.js und npm müssen installiert sein, damit Sie diesen Befehl ausführen können.

Die Anwendung verfügt über drei Routen:

  • /upload-image-url ermöglicht es Nutzern, ein Bild über eine URL hochzuladen. Die Route ist öffentlich zugänglich und scheint auf den ersten Blick harmlos.

  • /users gibt alle Informationen zu den Nutzern Ihrer Anwendung zurück. Die Route sollte nicht öffentlich zugänglich sein.

  • /users/:id/profile gibt das Profil eines bestimmten Nutzers zurück. Die Route sollte nicht öffentlich zugänglich sein.

Starten Sie die Anwendung mit folgendem Befehl:

node index.js

Wenn Sie mit Insomnia (oder einem anderen API-Testtool) eine Anfrage an /upload-image-url mit einer gültigen Bild-URL senden, sollten Sie folgende Antwort erhalten:

API-Client mit einer Anfrage zum Hochladen einer Bild-URL an localhost und einer 200-OK-Antwort mit zurückgegebenem HTML von Imgur

Wenn böswillige Nutzer diese Antwort erhalten, wissen sie, dass Ihr Server intern API-Aufrufe mit der angegebenen URL ausführt. Nun können sie verschiedene URLs testen, um die interne Struktur Ihres Servers herauszufinden. Oder sie übermitteln URLs wie http://169.254.169.254 oder http://instance-data, um auf die Amazon Web Services (AWS)-Metadaten Ihrer Anwendung zuzugreifen, falls diese auf einer Amazon Elastic Compute Cloud (Amazon EC2)-Instanz ausgeführt wird. Diese Art von SSRF wird als Basic-SSRF bezeichnet.

Bei einer Basic-SSRF manipuliert ein Angreifer den Server so, dass dieser Anfragen an unbeabsichtigte Ressourcen sendet – häufig ohne direkte Kenntnis der internen Serverstruktur. In diesem Fall kann der Angreifer normalerweise die Antwort auf die Anfrage sehen.

Eine weitere Art von SSRF ist Blind-SSRF. Dabei sendet ein Angreifer SSRF-Anfragen, hat aber keinen direkten Zugriff auf die Antwort des Servers. Stattdessen nutzt er das Verhalten der Anwendung, um indirekt zu überprüfen, ob der SSRF-Angriff erfolgreich war.

Wenn ein Angreifer beispielsweise die URL localhost:8050/users ausprobiert, erhält er folgende Antwort (d. h. eine Basic-SSRF), durch die alle Daten Ihrer Nutzer offengelegt werden:

API-Client mit einer POST-Anfrage zum Hochladen eines Bildes über eine URL und einer 200-OK-Antwort mit zurückgegebenen JSON-Daten

Ihr Code ist anfällig für SSRF-Angriffe, da er von Nutzern bereitgestellte URLs ohne angemessene Validierung oder Zugriffskontrolle akzeptiert. Dadurch können Nutzer Anfragen an potenziell sensible interne oder private Ressourcen senden. Außerdem gibt es keinen Mechanismus für eine Allowlist oder Denylist bestimmter Domains.

Um diese Sicherheitslücke zu beheben, sollten Sie Nutzereingaben bereinigen, den Zugriff auf vertrauenswürdige Domains beschränken, Firewalls verwenden und eine angemessene Fehlerbehandlung sowie Überwachung einrichten.

So verhindern Sie SSRF-Sicherheitslücken in Node.js

Wenn Sie SSRF-Sicherheitslücken in Ihrer Node.js-Anwendung verhindern möchten, stehen Ihnen verschiedene Möglichkeiten zur Verfügung. Im folgenden Abschnitt erfahren Sie mehr über einige Methoden und Best Practices.

Verwenden Sie die neuesten Bibliotheksversionen

Die Verwendung der neuesten Bibliotheksversionen ist ein wichtiger Bestandteil der Verbesserung der Anwendungssicherheit. Neue Versionen enthalten häufig kritische Sicherheitspatches und Fehlerbehebungen, durch die Ihre Anwendung weniger anfällig für gängige Angriffe wie SSRF wird.

Bei Aktualisierungen sollten Sie jedoch unbedingt Kompatibilitätsprobleme, Breaking Changes und Abwärtskompatibilität berücksichtigen. Behalten Sie Deprecation-Zyklen im Blick, aktualisieren Sie größere Codebasen schrittweise und analysieren Sie Abhängigkeiten regelmäßig auf potenzielle Sicherheitslücken. So bleibt Ihre Anwendung sicher und gut gewartet.

Mit Snyk können Sie Bibliotheken aktualisieren und Ihre Abhängigkeiten auf dem neuesten Stand sowie frei von öffentlich bekannten Sicherheitslücken halten.

Verwenden Sie eine Firewall

Eine Firewall ist ein Netzwerksicherheitssystem, das als Schutzbarriere dient und den Netzwerkverkehr anhand vordefinierter Regeln überwacht und steuert.

Um SSRF-Angriffe mithilfe von Firewalls zu verhindern, können Sie eine Web Application Firewall (WAF) einsetzen. Sie prüft und blockiert böswillige Anfragen, indem sie vertrauenswürdige Domains auf eine Allowlist setzt und verdächtige URLs oder IP-Adressen sperrt.

Bereinigen Sie Nutzereingaben

Die Bereinigung von Eingaben ist eine Sicherheitsmaßnahme, mit der Sie von Nutzern bereitgestellte Daten bereinigen und ändern können, damit sie sicher innerhalb Ihrer Anwendung verarbeitet werden können. Sie dient in erster Linie dazu, Sicherheitslücken zu verhindern, die durch nicht vertrauenswürdige oder böswillige Eingaben entstehen können.

Sie können SSRF verhindern, indem Sie alle Nutzereingaben bereinigen. So stellen Sie sicher, dass URLs korrekt formatiert sind und keine unerwarteten Zeichen enthalten, bevor Ihre Anwendung sie verarbeitet.

Die Bereinigung von Eingaben kann dazu beitragen, dass URLs korrekt formatiert sind. Sie sollten sie jedoch nicht als alleinige Maßnahme einsetzen.

Schränken Sie URL-Schemata ein

Eine weitere Möglichkeit, SSRF-Sicherheitslücken zu verhindern, ist die Vorgabe bestimmter URL-Schemata. Indem Sie die zulässigen URL-Schemata Ihrer Anwendung festlegen (z. B. HTTP und HTTPS), können Sie verhindern, dass Nutzer URLs mit potenziell gefährlichen oder unerwünschten Schemata eingeben (z. B. file:// und ftp://).

Um dies in der zuvor geklonten Anwendung umzusetzen, können Sie ausdrücklich prüfen, ob die angegebene URL mit einem zulässigen Schema beginnt, in der Regel http:// oder https://. Entspricht die URL diesen Schemata nicht, können Sie sie zurückweisen:

const validURLPattern = /^https?:\/\//;
const imageURL = req.body.imageURL;

if (!imageURL || !validURLPattern.test(imageURL)) {
  return res.status(400).send("Invalid or missing image URL");
}

Erstellen Sie eine Allowlist mit vertrauenswürdigen Domains

Eine Allowlist mit vertrauenswürdigen Domains verhindert SSRF-Sicherheitslücken, indem sie Anfragen ausschließlich an bestimmte Domains zulässt, die bekanntermaßen sicher und für Ihre Anwendung erforderlich sind.

Um dies in der zuvor geklonten Anwendung umzusetzen, erstellen Sie ein Array (in einer realen Anwendung benötigen Sie möglicherweise eine robustere Lösung), das die Domains enthält, denen Sie vertrauen und die Ihre Anwendung anfragen darf. Dabei sollte es sich um Domains handeln, mit denen Ihre Anwendung interagiert und die sie als sicher einstuft.

Prüfen Sie anschließend vor dem Senden einer Anfrage an die vom Nutzer angegebene URL, ob sie mit einer der vertrauenswürdigen Domains in Ihrer Liste übereinstimmt. Wenn nicht, blockieren Sie die Anfrage. Nach dieser Änderung sollte Ihre Route /upload-image-url so aussehen:

app.post("/upload-image-url", async (req, res) => {
  try {
    const trustedDomains = [
      "https://unsplash.com/",
      "https://example.com",
      "https://pexels.com/",
    ];

    const imageURL = req.body.imageURL;

    if (!imageURL) {
      return res.status(400).send("Image URL is required");
    }

    let isTrustedDomain = false;

    for (const domain of trustedDomains) {
      if (imageURL.startsWith(domain)) {
        isTrustedDomain = true;
        break;
      }
    }

    if (!isTrustedDomain) {
      return res.status(403).send("Access to this domain is not permitted.");
    }

    // Proceed with the request to the trusted domain.
    const image = await axios.get(imageURL);

    return res.json({
      response: "Image uploaded successfully",
      image: image.data,
    });
  } catch (error) {
    if (axios.isAxiosError(error)) {
      return res.status(error.response.status).send(error.response.data);
    }

    res.status(500).send("Something went wrong");
  }
});

Dieser Code ändert die Route /upload-image-url, indem er ein Array zulässiger Domains hinzufügt, prüft, ob die vom Nutzer angegebene URL auf der Allowlist steht, und die Anfrage zurückweist, wenn dies nicht der Fall ist.

Erkennen Sie Sicherheitslücken mit der Snyk-IDE-Erweiterung

Snyk ist ein beliebtes Sicherheitstool, mit dem sich Sicherheitslücken, darunter SSRF, in Open-Source-Bibliotheken erkennen und beheben lassen. Snyk bietet Integrationen für verschiedene Entwicklungsumgebungen und IDEs, darunter Visual Studio Code (VS Code).

Um die Snyk-IDE-Erweiterung in VS Code zu installieren, öffnen Sie die Ansicht Erweiterungen. Klicken Sie dazu in der linken Seitenleiste auf das quadratische Symbol oder drücken Sie Ctrl + Shift + X (unter macOS Cmd + Shift + X):

Ansicht „Erweiterungen“ in Visual Studio Code mit einer Suche nach „Snyk“ und den Details zur installierten Erweiterung Snyk Security

Suchen Sie im Erweiterungs-Marktplatz nach „Snyk“ und klicken Sie neben der Snyk-Erweiterung auf die Schaltfläche Installieren:

Visual Studio Code zeigt die Seite der Snyk Security-Erweiterung mit Details zum Code-Scanning und Installationsoptionen

Nach der Installation müssen Sie die Erweiterung mit Ihrem Snyk-Konto authentifizieren. Falls Sie noch kein Snyk-Konto haben, registrieren Sie sich jetzt. Klicken Sie auf das Snyk-Symbol und melden Sie sich mit Ihren Snyk-Zugangsdaten an.

Öffnen Sie als Nächstes in VS Code das Projekt-Repository, das Sie geklont haben. Es sollte eine Aufforderung erscheinen, ob Snyk diesen Ordnern vertrauen soll. Klicken Sie auf Ordnern vertrauen und fortfahren:

Ein Snyk-Warndialog weist darauf hin, dass beim Scannen Code ausgeführt werden kann, und empfiehlt, nur vertrauenswürdige Ordner zu scannen. Es stehen Optionen zur Verfügung, um Ordner als vertrauenswürdig einzustufen oder abzulehnen.

Bei den Codezeilen mit Sicherheitslücken sollten rote Wellenlinien zu sehen sein (d. h. bei axios.get in Zeile 19). Wenn Sie den Mauszeiger über eine Wellenlinie bewegen, wird ein Fenster mit Erläuterungen zur Sicherheitslücke angezeigt.

JavaScript-Code in VS Code mit einer Sicherheitswarnung, die eine SSRF-Schwachstelle in einem axios.get-Aufruf identifiziert.

Alternativ können Sie auf das Snyk-Symbol klicken und CODE SECURITY auswählen, um Sicherheitsprobleme anzuzeigen. Wenn Sie eine bestimmte Sicherheitslücke auswählen, öffnet Snyk die linke Seitenleiste und zeigt Codebeispiele an, mit denen Sie das Problem beheben können.

Snyk Code-Panel für Sicherheitslücken mit einer Server-Side-Request-Forgery-Schwachstelle im Node.js-Code, bei der axios eine Bild-URL aus einer Benutzereingabe anfordert

Fazit

In diesem Artikel haben Sie erfahren, wie wichtig es ist, Ihre Node.js-Anwendungen vor SSRF zu schützen, und welche Strategien und Best Practices Ihnen dabei helfen können.

Mit aktuellen Bibliotheksversionen, festgelegten URL-Schemata, Allowlists und Sicherheitstools wie Snyk können Sie die Wahrscheinlichkeit von SSRF-Sicherheitslücken in Ihren Anwendungen deutlich reduzieren. Wenn Sie Snyk in Ihren Entwicklungsworkflow integrieren, können Sie SSRF und andere Sicherheitslücken effizient erkennen, bevor sie in die Produktion gelangen. So stärken Sie Ihren Code und schützen Ihre Systeme vor potenziellen Angriffen.

Warten Sie nicht länger! Schützen Sie Ihre Anwendungen ab sofort mit Snyk!

Starten Sie mit Capture-the-Flag

Erfahren Sie, wie Sie Capture-the-Flag-Herausforderungen lösen – mit unserem jederzeit verfügbaren virtuellen 101-Workshop.

Weiterlesen

feature insights context
Blog

Autonome Angriffe sind bereits Realität. Die Verteidigung muss Schritt halten.

Autonome Angreifer verkürzen das Zeitfenster für die Verteidigung. Erfahren Sie, wie kontinuierliches Erkennen, Beheben, Validieren und Verhindern Sicherheitsteams helfen kann, Schritt zu halten.

illustration hero ai
Blog

Der KI-Hurrikan ist da

KI beschleunigt gleichermaßen die Softwareentwicklung und Cyberangriffe. Führungskräfte müssen Agents und Code von Anfang an absichern, zur Laufzeit Kontrollen durchsetzen und Abwehrmaßnahmen unabhängig validieren.

feature insights context
Blog

Ist Prävention im Grunde ein gelöstes Problem?

Die Prävention in von Agenten generiertem Code ist architektonisch gelöst – die Herausforderung besteht jedoch weiterhin darin, Kontrollen zu wählen, die die Sicherheit schützen, ohne die Entwicklung zu verlangsamen.