
Ihr Team hat mehrere Sprints lang an einer Webanwendung gearbeitet. Sie bereiten sich jetzt auf die erste offizielle Freigabe für die Produktionsumgebung vor, in der die Endbenutzer Konten registrieren und mit ihren Daten interagieren werden. Die User Stories sind implementiert, getestet und bereit für den Einsatz. Es gibt nur noch eine letzte Hürde zu überwinden: die Sicherheitsprüfung.
Ein Team von Sicherheitsexperten wird Ihre Webanwendung von oben bis unten überprüfen und versuchen, die Anwendung zu missbrauchen, um Zugriff auf Daten zu erhalten, die sie nicht sehen sollen, oder - noch schlimmer - auf das Dateisystem, auf dem die Webanwendung gehostet wird. Aber keine Panik! Lassen Sie uns einige Schritte durchgehen, die Ihr Team unternehmen kann - und sollte -, um sich auf die Sicherheitsüberprüfung vorzubereiten.
Sammeln Sie Informationen über Ihr System
Der erste Schritt besteht darin, alles über Ihre Webanwendung, die Akteure und die Infrastruktur, die sie verwendet oder mit der sie eine Schnittstelle bildet, zu wissen. Das bedeutet, dass Sie wahrscheinlich weitere Personen aus verschiedenen Abteilungen hinzuziehen müssen, um alle Fragen zu beantworten: das Entwicklungsteam, die Infrastruktur, DevOps, Architekten und jemanden von den Sicherheitsbeauftragten.
Hier sind einige Fragen, die Ihnen den Einstieg erleichtern:
- Welche Frameworks verwenden wir in unserem Code (.NET, Java, React, Xamarin, ...) und welche Abhängigkeiten haben wir (NuGet, Maven, NPM, ...)? Verwenden wir nach Möglichkeit die neuesten Versionen? Wissen wir, warum einige Versionen zurückbleiben müssen? Gibt es Alternativen?
- Wie werden unsere Anwendungen zur Laufzeit konfiguriert? Sind statische Dateien von der Außenwelt zugänglich? Werden die Geheimnisse während des Bereitstellungsprozesses geschützt oder sind sie jederzeit sichtbar?
- Mit welchen Diensten interagieren wir, sowohl intern als auch extern? Wie werden ihre Interaktionen geschützt? Denken Sie an Anmeldedaten, Zertifikate, Firewall-Regeln, ausdrücklich erlaubte IP-Adressbereiche, ...
- Wo werden die Komponenten unserer Webanwendung gehostet und wie ist die Umgebung konfiguriert? Verwenden wir ein virtuelles Netzwerk, sind die Webserver für die Verwendung der neuesten TLS-Version konfiguriert oder nicht? Verfügen wir über einen zusätzlichen Schutz für unsere Komponenten, wie eine Firewall und/oder eine API-Verwaltungsschicht?
- Wenn Ihre Anwendung mehrere Rollen/Rechte pro Benutzer oder Aktion hat, haben Sie dann einen klaren Überblick pro Ressource, Aktion und Benutzertyp oder Rolle, welche Aktionen erlaubt oder abgelehnt werden sollten?
Erstellen Sie ein Bedrohungsmodell
Nachdem Sie viele Informationen gesammelt haben, ist es an der Zeit, das System zu visualisieren und die Interaktionen zwischen allen Komponenten hervorzuheben. Es gibt mehrere Tools zur Bedrohungsmodellierung, die Sie bei diesem Prozess unterstützen. Eines der ältesten Tools ist das Microsoft Threat Modeling Tool, das sich auf den Microsoft-Technologie-Stack konzentriert und als Windows-Client auf der Microsoft Threat Modeling Tool-Website frei verfügbar ist.
Unabhängig davon, welches Bedrohungsmodellierungstool Sie letztendlich verwenden, haben sie alle gemeinsam, dass sie es einfacher machen, potenzielle Schwachstellen oder Risiken für jede Interaktion im Modell zu ermitteln. Wenn Sie zum Beispiel eine Interaktion zwischen einem Webserver und einer SQL-Datenbank hinzufügen, ist eines der identifizierten Risiken: "Ein Angreifer kann aufgrund einer schwachen Netzwerksicherheitskonfiguration unbefugten Zugriff auf die SQL-Datenbank erhalten." In Azure könnte dies bedeuten, dass Sie die SQL-Datenbank so konfiguriert haben, dass der Zugriff von allen Netzwerken oder sogar von allen Azure-Diensten aus möglich ist. Das ist ein Risiko, da diese Option auch Azure-Dienste umfasst, die von anderen Azure-Kunden verwaltet werden.
Im folgenden Screenshot sehen Sie ein Beispiel für ein Bedrohungsmodell für eine Webanwendung, die direkt mit einer SQL Server-Instanz kommuniziert. Azure Traffic Manager wird vor dem Azure App Service platziert, um den vom Browser eines Benutzers kommenden Datenverkehr an mehrere Instanzen des App Service umzuleiten. Der Kürze halber wurden diese mehreren Instanzen im Diagramm weggelassen. Zwischen jeder Komponente oder jedem Akteur im Diagramm wurden Anfrage- und Antwortflüsse eingefügt, um zu zeigen, wie die Komponenten miteinander interagieren:
Abbildung 1 - Entwerfen eines Bedrohungsmodells
Nachdem Sie das Bedrohungsmodell entworfen haben, können Sie mit dem Threat Modeling Tool von Microsoft einen Bericht erstellen. Dieser Bericht analysiert alle gezeichneten Interaktionen und erstellt je nach den konfigurierten Attributen eine Liste potenzieller Risiken pro Interaktion oder Komponente, wie im folgenden Screenshot zu sehen ist.
Abbildung 2 - Beispiel für ein identifiziertes Risiko
Der oben gezeigte Bericht über das Bedrohungsmodell hebt die Anfrage zwischen dem TodoItems MVC-App-Dienst und der SQL-Datenbank TodoItemsDb hervor und hat ein potenzielles Risiko identifiziert:
Ein Angreifer kann aufgrund einer schwachen Kontorichtlinie unbefugten Zugriff auf die Azure SQL-Datenbank erhalten.
Jedes identifizierte Risiko sollte bewertet und vom Bewertungsteam besprochen werden, um über die nächsten Schritte zu entscheiden. Denken Sie bei der Bemessung eines Risikos an die Auswirkungen, die ein ausgenutztes Risiko hat, z.B. anhand des DREAD-Modells:
- Schaden: Wie groß wäre der Schaden?
- Reproduzierbarkeit: Wie einfach ist es, den Exploit zu reproduzieren?
- Ausnutzbarkeit: Wie viel Arbeit ist es, den Exploit auszuführen, damit er funktioniert?
- Betroffene Nutzer: Wie viele Menschen wären davon betroffen?
- Entdeckbarkeit: Wie einfach ist es, die Bedrohung zu entdecken?
Der letzte Buchstabe von DREAD, Auffindbarkeit, ist jedoch mit Vorsicht zu genießen: Es ist leicht, ein Risiko als schwer auffindbar abzutun, zum Beispiel wenn Konfigurationsdateien, die Geheimnisse enthalten, nicht auffindbar sind, weil der Webserver keine Verzeichnisinhalte auflistet. Aber wenn ein Angreifer weiß, dass Ihre Anwendung ein bestimmtes Framework verwendet, das eine Datei namens "appsecrets.xml" unter dem Pfad "/config" erwartet, und er trotzdem auf diese Datei zugreifen kann, könnte sich ein geringes Risiko in ein sehr großes Problem verwandeln.
Sie haben Informationen gesammelt, ein Modell erstellt und die Risiken abgeschätzt. Doch bevor Sie Ihre neue Webanwendung von den Sicherheitsexperten prüfen lassen, sollten Sie prüfen, ob es nicht schon einige Punkte gibt, die Sie verbessern können.
Härtung der Anwendung
Noch bevor die allererste Sicherheitsüberprüfung stattfindet, kann es nicht schaden, von Anfang an Sicherheitsfunktionen zu implementieren. Einige Sicherheitsvorkehrungen können zwar zu jedem beliebigen Zeitpunkt während der Entwicklung einer Anwendung implementiert werden, aber andere sind viel einfacher zu implementieren, wenn Sie von Anfang an an sie denken: z.B. die Content-Security-Policy, die später in diesem Artikel beschrieben wird.
Absicherung des Netzwerks
In unserem Beispieldiagramm laufen ein SQL Server und ein Azure App Service innerhalb eines Azure Trust Boundary-Netzwerks: Alle Dienste innerhalb dieser Grenze können frei miteinander kommunizieren. Dies schränkt jedoch nicht den Zugriff auf unsere spezifische Ressourcengruppe ein, sondern erlaubt auch jedem anderen in Azure gehosteten Dienst, auf die Ressourcen unserer Anwendung zuzugreifen.
Um unerwünschten Zugriff zu verhindern, können wir ein virtuelles Netzwerk in Azure konfigurieren. In diesem virtuellen Netzwerk fügen wir den App Service und die SQL-Datenbank hinzu und erlauben dem Azure Traffic Manager nur den Zugriff auf den App Service von außerhalb des virtuellen Netzwerks. Dadurch wird sichergestellt, dass nur die Azure App Service-Instanzen auf die SQL-Datenbank zugreifen können.
HTTPS für alle Dinge!
Beginnen wir mit der grundlegendsten Regel, die jeder vom ersten Tag an für seine Webanwendungen anwenden sollte: Verwenden Sie überall HTTPS, auch während der Entwicklung. Wenn das bedeutet, dass Sie ein selbstsigniertes lokales Zertifikat für Ihre lokale Entwicklungsumgebung erstellen müssen, dann ist das in Ordnung, aber verwenden Sie von Anfang an HTTPS.
Dies gilt auch für containerisierte Anwendungen: Bitte unterlassen Sie es, nur die externen Endpunkte zu schützen und dann auf HTTP-Verkehr innerhalb des Container-Netzwerks umzuschalten! Wenn Sie sich nur darauf konzentrieren, die äußere Schicht zu schützen, ist die Wahrscheinlichkeit groß, dass diese Methode ihren Weg in die Produktionsumgebung findet. Und wenn es jemandem mit böswilligen Absichten gelingt, seinen eigenen Container in Ihrem Netzwerk einzusetzen, dann ist das Spiel vorbei. Aber um ehrlich zu sein, wenn das passieren würde, gibt es wahrscheinlich auch andere Systeme, die Ihre sofortige Aufmerksamkeit benötigen.
HTTP-Header hinzufügen oder entfernen
Jede Webanwendung sollte mit dem korrekten Satz von HTTP-Headern antworten. Die meisten Webserver und Anwendungs-Frameworks fügen jedoch einige Informationen in diese HTTP-Header ein, die sofort verraten, welcher Server oder welches Framework auf dem System läuft. Die Kombination dieser Daten könnte für jemanden ausreichen, um einen spezifischen Angriff zu starten, indem er einfach eine CVE (Common Vulnerability and Exposure) nachschlägt.
Abbildung 3 - Beispiel einer HTTP-Anfrage mit Anzeige der Antwort-Header
Als ich eine Website besuchte, war dies die Antwort, die mein Browser erhielt, was mir drei wichtige Dinge sagt:
- Auf dem Webserver läuft Apache in der Version 2.4.39, wie aus dem Server-HTTP-Header hervorgeht. Derzeit ist die neueste Version 2.4.52, und das jüngste Update enthält zwei Korrekturen für CVEs.
- Auf dem Webserver läuft Ubuntu Linux, was auch durch den gleichen Server HTTP-Header verraten wird. Wir erhalten zwar keine Versionsnummer, aber die Kombination von Apache und Ubuntu könnte uns zu bestimmten Sicherheitslücken führen.
- Die Website verwendet WordPress. Das ist etwas schwieriger herauszufinden, aber wenn Sie sich den ersten Link-Header genau ansehen, werden Sie wp-json und einen Verweis auf die WordPress-API sehen. Dieser oder jeder andere Header verrät uns zwar nicht die Versionsnummer, aber die lässt sich leicht im Quellcode der Seite finden. In diesem Fall verwendet die Website die WordPress-Version 5.2.3, während 5.8.3 die aktuellste Version ist.
Mit nur zwei HTTP-Headern, die völlig harmlos zu sein scheinen, und ein wenig Nachforschung auf der zurückgegebenen Webseite haben wir genug Informationen erhalten, um nach Möglichkeiten zu suchen, die Kontrolle über diese Website oder sogar den Server zu erlangen. Wäre dieser Webserver so konfiguriert gewesen, dass er den Server-HTTP-Header nicht sendet, hätte sich mein Angriffsvektor erheblich verringert.
Einige Anwendungsframeworks neigen dazu, einen eigenen HTTP-Header, X-Powered-By, hinzuzufügen, um anzukündigen, dass ein Framework verwendet wird, wobei oft auch eine Versionsnummer angegeben wird:
X-Powered-By: PHP/5.4.0
Diese Informationen sind eine Goldgrube für Hacker! Tun Sie sich selbst einen Gefallen und entfernen Sie diesen Header ebenfalls aus jeder HTTP-Antwort.
Andere HTTP-Header sind es jedoch wert, in Ihre Anwendung aufgenommen zu werden, um Ihre Webanwendungen sicherer zu machen:
- Strict-Transport-Security: Dieser Header teilt dem Browser mit, dass Ihre Website immer HTTPS unterstützt. Sie können diese Information auch vorladen, indem Sie Ihre Website auf der HSTS Preload-Liste ankündigen. Dies ermöglicht es Browsern, Besucher sofort auf HTTPS umzuleiten, auch wenn sie Ihre Website noch nie zuvor besucht haben.
- Content-Security-Policy: Kurz gesagt, wird dieser Header verwendet, um anzugeben, welche Quellen von der Webanwendung verwendet werden dürfen oder nicht. Denken Sie an CSS-Stile, Schriftarten, JavaScript, aber auch an AJAX-Anfragen, das Hosten von gerahmten Inhalten oder das Hosten als Frame usw. Das Einrichten eines guten CSP-Headers (Content-Security-Policy) ist jedoch eine gewaltige Aufgabe und erfordert höchstwahrscheinlich auch das Umschreiben von Teilen der Anwendung, wenn diese stark auf JavaScript basiert. Was auch immer Sie tun, gehen Sie nicht den einfachen Weg und geben Sie "unsafe-inline" für die script-src-Direktive an, denn das würde Ihre Webanwendung für die Ausführung von JavaScript öffnen. Für weitere Informationen empfehle ich Ihnen die Richtlinien zur Content Security Policy und die CSP-Dokumentation des Mozilla Developer Network
Ist Ihre Keksdose sicher?
Serverseitige Webanwendungen verwenden Cookies, um zu speichern, ob ein Besucher authentifiziert ist, um seinen Einkaufswagen, seine Sprachpräferenz und viele andere Dinge zu speichern. Aber sind Ihre Cookies richtig gesichert?
Cookies sollten als "HttpOnly" und "Sicher" gekennzeichnet sein und die richtige SameSite-Richtlinie sollte auf sie angewendet werden:
- HttpOnly verhindert, dass Cookies in JavaScript verwendet werden. Ein Cookie für die Spracheinstellung muss nicht mit HttpOnly markiert werden, damit ein Skript einen Datumswert mit dem richtigen Gebietsschema formatieren kann. JavaScript sollte jedoch niemals Zugriff auf die Werte von Authentifizierungs-Cookies haben, so dass diese Cookies als HttpOnly markiert werden sollten.
- Sicher bedeutet, dass das Cookie nur über HTTPS-Verbindungen gesendet wird.
- SameSite definiert oder begrenzt, wie Ihre Cookies fließen können. Die strengste Einstellung schränkt ein, dass Cookies nur dann gesendet werden, wenn der Benutzer auf der Website interagiert, während die am wenigsten sichere Einstellung es erlaubt, dass Cookies auch dann gesendet werden, wenn der Benutzer z.B. auf einen Link in einer E-Mail klickt. Weitere Informationen finden Sie unter SameSite-Cookies erklärt auf web.dev.
Und genau wie bei den HTTP-Headern Server und X-Powered-By enthalten einige Cookie-Namen einen klaren Hinweis auf das von der Webanwendung verwendete Framework. Wenn Sie zum Beispiel die Cookie-basierte Authentifizierung in ASP.NET Core verwenden, sehen Sie ein Cookie mit dem Namen ".AspNetCore.Cookies". Es ist sehr einfach, diese Cookies umzukonfigurieren und umzubenennen. So wird es für potenzielle Angreifer weniger offensichtlich, mit welchem Framework Ihre Webanwendung erstellt wurde.
Und viele mehr...
Es gibt immer noch eine Reihe von Schritten zur Anwendungshärtung, die Sie abhängig von Ihrer Architektur und der Funktionalität der Webanwendung unternehmen können:
- Beim Parsen von XML können möglicherweise externe Daten während des Parsens geladen werden
- Hochgeladene Dateien könnten Viren enthalten, oder Uploads könnten versuchen, Daten von anderen Benutzern oder das System zu überschreiben
- Für jeden Datenspeichertyp gibt es eine Form von Injektionsangriffen. Stellen Sie also sicher, dass Sie Ihre Abfragen richtig parametrisieren.
- Verwendet Ihre containerisierte Anwendung ein bekanntes Basis-Image oder eines, das Sie zufällig irgendwo gefunden haben? Wenden Sie selbst Patches an? Dann halten Sie auch diese auf dem neuesten Stand
Fazit
Durch das Sammeln von Wissen über Ihr System und die Erstellung eines Bedrohungsmodells wird deutlich, worauf Sie als Team Ihre Bemühungen konzentrieren müssen, um Ihre Webanwendung sicherer zu machen, noch bevor die eigentliche Sicherheitsbewertung beginnt. Und wenn Sie die Extrameile gehen und bereits einige zusätzliche Korrekturen implementieren, dann wird das Sicherheitsteam höchstwahrscheinlich positiv überrascht und herausgefordert sein, noch gründlicher zu testen.
In jedem Fall werden Sie besser auf die Sicherheitsprüfung vorbereitet sein, und gemeinsam werden Sie eine sicherere Lösung liefern können.
Wir befinden uns im digitalen Zeitalter, in dem Sicherheit wichtiger denn je ist. Allein im vergangenen Jahr hatten wir es mit der Log4Shell-Schwachstelle, mehreren Zero-Day-Schwachstellen für Microsoft Exchange und 15 bekannten Datenschutzverletzungen mit über 87.811.266 Datensätzen
Inzwischen verlassen sich Entwicklungsteams bei der Erstellung von Softwarelösungen mehr und mehr auf externe Softwarebibliotheken und Container-Images. Und auch hier gibt es Berichte über Versuche, bösartige Nutzdaten in Codebibliotheken einzuschleusen[4], während Container-Images sehr schnell veraltet sein können.
Aus diesem Grund wenden immer mehr Unternehmen präventiv Sicherheitsbewertungen für ihre Projekte und Teams an. Teams können aber auch proaktiv zusammenarbeiten, um sicherere Lösungen zu entwickeln: Scannen Sie externe Bibliotheken und Container-Images kontinuierlich während der Builds, härten Sie Webanwendungen durch Code ab und richten Sie sichere Netzwerkumgebungen ein.
[1] Wikipedia-Liste der Datenschutzverletzungen
[2] Liste der Hackerangriffe auf die Sicherheit im Jahr 2021
Verfasst von

Wesley Cabus
Contact