CSRF-, XSSI- und plattformübergreifende Datenlecks verhindern
Warum sollten Sie Ihre Webressourcen isolieren?
Viele Webanwendungen sind anfällig für Cross-Origin-Angriffe wie Cross-Site Request Forgery (CSRF), Cross-Site Script Inclusion (XSSI), Timing-Angriffe, Cross-Origin Information Leaks oder spekulative Ausführungs-Side-Channel-Angriffe (Spectre).
Mit den Anfrageheadern Fetch Metadata können Sie einen starken Defense-in-Depth-Mechanismus – eine Ressourcenisolierungsrichtlinie – implementieren, um Ihre Anwendung vor diesen gängigen plattformübergreifenden Angriffen zu schützen.
Häufig werden Ressourcen, die von einer bestimmten Webanwendung bereitgestellt werden, nur von der Anwendung selbst und nicht von anderen Websites geladen. In solchen Fällen ist die Implementierung einer Ressourcenisolierungsrichtlinie, die auf Anfrageheadern für das Abrufen von Metadaten basiert, mit wenig Aufwand verbunden und schützt gleichzeitig die Anwendung vor websiteübergreifenden Angriffen.
Browserkompatibilität
Anfrageheader zum Abrufen von Metadaten werden in allen modernen Browser-Engines unterstützt.
Hintergrund
Viele websiteübergreifende Angriffe sind möglich, weil das Internet standardmäßig offen ist und Ihr Anwendungsserver sich nicht so einfach vor der Kommunikation von externen Anwendungen schützen kann. Ein typischer ursprungsübergreifender Angriff ist Cross-Site Request Forgery (CSRF), bei dem ein Angreifer einen Nutzer auf eine von ihm kontrollierte Website lockt und dann ein Formular an den Server sendet, bei dem der Nutzer angemeldet ist. Da der Server nicht erkennen kann, ob die Anfrage von einer anderen Domain stammt (websiteübergreifend), und der Browser automatisch Cookies an websiteübergreifende Anfragen anhängt, führt der Server die vom Angreifer angeforderte Aktion im Namen des Nutzers aus.
Andere websiteübergreifende Angriffe wie Cross-Site Script Inclusion (XSSI) oder ursprungsübergreifende Informationslecks sind ähnlich wie bei CSRF. Dabei werden Ressourcen aus einer Opferanwendung in ein von Angreifern kontrolliertes Dokument geladen und Informationen über die Anwendungen des Opfers offengelegt. Da Anwendungen vertrauenswürdige Anfragen nicht einfach von nicht vertrauenswürdigen Anfragen unterscheiden können, können sie schädlichen websiteübergreifenden Traffic nicht verwerfen.
Jetzt neu: „Metadaten abrufen“
Anfrageheader zum Abrufen von Metadaten sind eine neue Sicherheitsfunktion für Webplattformen, mit der sich Server vor ursprungsübergreifenden Angriffen schützen können. Durch die Bereitstellung von Informationen zum Kontext einer HTTP-Anfrage in einer Reihe von Sec-Fetch-*
-Headern können die antwortenden Server Sicherheitsrichtlinien anwenden, bevor die Anfrage verarbeitet wird. So können Entwickler entscheiden, ob sie eine Anfrage annehmen oder ablehnen möchten, je nachdem, wie sie gestellt wurde und in welchem Kontext sie verwendet wird. So ist es möglich, nur auf legitime Anfragen zu reagieren, die von ihrer eigenen Anwendung stammen.
Sec-Fetch-Site
Sec-Fetch-Site
teilt dem Server mit, von welcher Website die Anfrage gesendet wurde. Der Browser legt diesen Wert auf einen der folgenden Werte fest:
same-origin
, wenn die Anfrage von Ihrer eigenen Anwendung (z.B.site.example
) gestellt wurdesame-site
, wenn die Anfrage von einer Subdomain Ihrer Website stammt (z. B.bar.site.example
)none
, wenn die Anfrage explizit durch die Interaktion eines Nutzers mit dem User-Agent verursacht wurde (z. B. Klicken auf ein Lesezeichen)cross-site
, wenn die Anfrage von einer anderen Website gesendet wurde (z. B.evil.example
)
Sec-Fetch-Mode
Sec-Fetch-Mode
gibt den Modus der Anfrage an. Dies entspricht ungefähr dem Typ der Anfrage und ermöglicht es Ihnen, Ressourcenlasten von Navigationsanfragen zu unterscheiden. Ein Ziel von navigate
gibt beispielsweise eine Navigationsanfrage auf oberster Ebene an, während no-cors
für Ressourcenanfragen wie das Laden eines Bildes steht.
Sec-Fetch-Dest
Sec-Fetch-Dest
macht das Ziel einer Anfrage verfügbar, z.B. wenn ein script
- oder ein img
-Tag dazu geführt hat, dass eine Ressource vom Browser angefordert wurde.
Fetch Metadata zum Schutz vor plattformübergreifenden Angriffen verwenden
Die zusätzlichen Informationen, die diese Anfrageheader liefern, sind recht einfach, aber der zusätzliche Kontext ermöglicht es Ihnen, mit nur wenigen Codezeilen eine leistungsstarke Sicherheitslogik auf der Serverseite zu erstellen, die auch als Richtlinie zur Ressourcenisolierung bezeichnet wird.
Richtlinie zur Ressourcenisolierung implementieren
Eine Richtlinie zur Ressourcenisolierung verhindert, dass Ihre Ressourcen von externen Websites angefordert werden. Durch das Blockieren solcher Zugriffe werden häufige Cross-Site-Web-Sicherheitslücken wie CSRF, XSSI, Timing-Angriffe und Cross-Origin-Informationslecks minimiert. Diese Richtlinie kann für alle Endpunkte Ihrer Anwendung aktiviert werden und erlaubt alle Ressourcenanfragen, die von Ihrer eigenen Anwendung stammen, sowie direkte Navigationen (über eine HTTP-GET
-Anfrage). Für Endpunkte, die in einem websiteübergreifenden Kontext geladen werden sollen (z.B. Endpunkte, die mit CORS geladen werden), kann diese Logik deaktiviert werden.
Schritt 1: Anfragen von Browsern zulassen, die keine Abrufmetadaten senden
Da das Abrufen von Metadaten nicht von allen Browsern unterstützt wird, müssen Sie Anfragen ohne Sec-Fetch-*
-Header zulassen, indem Sie prüfen, ob sec-fetch-site
vorhanden ist.
if not req['sec-fetch-site']:
return True # Allow this request
Schritt 2: Anfragen innerhalb der Website und vom Browser initiierte Anfragen zulassen
Alle Anfragen, die nicht aus einem ursprungsübergreifenden Kontext wie evil.example
stammen, werden zugelassen. Dazu gehören insbesondere Anfragen, die:
- Sie stammen aus Ihrer eigenen Anwendung (z. B. eine Anfrage vom selben Ursprung, bei der
site.example
-Anfragensite.example/foo.json
immer zulässig sind). - Sie stammen aus Ihren Subdomains.
- Werden explizit durch die Interaktion eines Nutzers mit dem User-Agent ausgelöst, z. B. durch direkte Navigation oder durch Klicken auf ein Lesezeichen
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True # Allow this request
Schritt 3: Einfache Navigation auf oberster Ebene und iFrames zulassen
Damit deine Website weiterhin von anderen Websites aus verlinkt werden kann, musst du eine einfache Navigation (HTTP GET
) auf oberster Ebene zulassen.
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
# <object> and <embed> send navigation requests, which we disallow.
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True # Allow this request
Schritt 4: Endpunkte deaktivieren, die für websiteübergreifende Zugriffe gedacht sind (optional)
In einigen Fällen stellt Ihre Anwendung möglicherweise Ressourcen bereit, die websiteübergreifend geladen werden sollen. Diese Ressourcen müssen pro Pfad oder Endpunkt ausgenommen werden. Beispiele für solche Endpunkte:
- Endpunkte, auf die über mehrere Ursprünge hinweg zugegriffen werden soll: Wenn Ihre Anwendung Endpunkte bereitstellt, für die
CORS
aktiviert ist, müssen Sie die Ressourcenisolierung für diese Endpunkte explizit deaktivieren, damit weiterhin websiteübergreifende Anfragen an diese Endpunkte möglich sind. - Öffentliche Ressourcen (z.B. Bilder, Stile usw.): Alle öffentlichen und nicht authentifizierten Ressourcen, die ursprungsübergreifend von anderen Websites geladen werden sollen, können ebenfalls ausgenommen werden.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
Schritt 5: Alle anderen websiteübergreifenden Anfragen ablehnen, die nicht auf Navigation zurückzuführen sind
Alle anderen websiteübergreifenden Anfragen werden von dieser Richtlinie zur Ressourcenisolierung abgelehnt und Ihre Anwendung wird so vor gängigen websiteübergreifenden Angriffen geschützt.
Beispiel:Der folgende Code zeigt eine vollständige Implementierung einer robusten Richtlinie zur Ressourcenisolierung auf dem Server oder als Middleware, mit der potenziell schädliche websiteübergreifende Ressourcenanfragen abgelehnt werden können. Gleichzeitig werden einfache Navigationsanfragen ermöglicht:
# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
# Allow requests from browsers which don't send Fetch Metadata
if not req['sec-fetch-site']:
return True
# Allow same-site and browser-initiated requests
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True
# Allow simple top-level navigations except <object> and <embed>
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True
# [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
# Reject all other requests that are cross-site and not navigational
return False
Richtlinie zur Ressourcenisolierung bereitstellen
- Installieren Sie ein Modul wie das obige Code-Snippet, um das Verhalten Ihrer Website zu protokollieren und zu überwachen und sicherzustellen, dass sich die Einschränkungen nicht auf legitimen Traffic auswirken.
- Beheben Sie potenzielle Verstöße, indem Sie legitime ursprungsübergreifende Endpunkte ausnehmen.
- Sie können die Richtlinie erzwingen, indem Sie nicht konforme Anfragen löschen.
Richtlinienverstöße erkennen und beheben
Wir empfehlen, die Richtlinie ohne Nebenwirkungen zu testen. Aktivieren Sie dazu die Richtlinie zuerst im Berichterstellungsmodus in Ihrem serverseitigen Code. Alternativ können Sie diese Logik in Middleware oder in einem Reverse-Proxy implementieren, der alle Verstöße protokolliert, die bei der Anwendung Ihrer Richtlinie auf Produktionszugriffe auftreten.
Unsere Erfahrung bei der Einführung einer Richtlinie für die Isolierung von Metadatenressourcen bei Google hat ergeben, dass die meisten Anwendungen standardmäßig mit einer solchen Richtlinie kompatibel sind und nur selten ausgenommene Endpunkte erforderlich sind, um websiteübergreifenden Traffic zu ermöglichen.
Ressourcenisolationsrichtlinie erzwingen
Nachdem Sie überprüft haben, dass sich Ihre Richtlinie nicht auf legitimen Produktionstraffic auswirkt, können Sie Einschränkungen erzwingen. So wird sichergestellt, dass andere Websites Ihre Ressourcen nicht anfordern können, und Ihre Nutzer werden vor websiteübergreifenden Angriffen geschützt.
Weitere Informationen
- W3C Fetch Metadata Request Headers – Spezifikation
- Metadaten-Playground
- Google I/O-Vortrag: Securing Web Apps with Modern Platform Features (Folien)