Ressourcen mit Fetch Metadata vor Webangriffen schützen

Verhindern Sie den Verlust von CSRF-, XSSI- und ursprungsübergreifenden Informationen.

Lukas Weichselbaum
Lukas Weichselbaum

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 Anfrageheadern zum Abrufen von Metadaten können Sie einen starken, gestaffelten Mechanismus – eine Richtlinie zur Ressourcenisolierung – implementieren, um Ihre Anwendung vor diesen häufigen ursprungsü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 Bereitstellung einer Richtlinie zur Ressourcenisolierung auf der Grundlage von Anfrageheadern zum Abrufen von Metadaten mit geringem 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.

Unterstützte Browser

  • Chrome: 76 <ph type="x-smartling-placeholder">
  • Edge: 79. <ph type="x-smartling-placeholder">
  • Firefox: 90. <ph type="x-smartling-placeholder">
  • Safari: 16.4 <ph type="x-smartling-placeholder">

Quelle

Hintergrund

Viele websiteübergreifende Angriffe sind möglich, weil das Internet standardmäßig offen ist und Ihr Anwendungsserver sich nicht problemlos 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 feststellen kann, ob die Anfrage von einer anderen Domain (websiteübergreifend) stammt, und der Browser den websiteübergreifenden Anfragen automatisch Cookies hinzufügt, 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.

Neu: Abruf von Metadaten

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 kann der antwortende Server vor der Verarbeitung der Anfrage Sicherheitsrichtlinien anwenden. Entwickler können dann basierend auf der Art und dem Kontext, in dem sie verwendet wird, entscheiden, ob sie eine Anfrage annehmen oder ablehnen. So können sie nur auf legitime Anfragen ihrer eigenen Anwendung antworten.

Gleicher Ursprung
<ph type="x-smartling-placeholder"></ph> Anfragen von Websites, die von Ihrem eigenen Server (same-Origin) bereitgestellt werden, funktionieren weiterhin. Eine Abrufanfrage von https://site.example für die Ressource https://site.example/foo.json in JavaScript veranlasst den Browser, den HTTP-Anfrageheader „Sec Fetch-Site: same-origin“ zu senden.
Websiteübergreifend
<ph type="x-smartling-placeholder"></ph> Schädliche websiteübergreifende Anfragen können vom Server aufgrund des zusätzlichen Kontexts in der HTTP-Anfrage von Sec-Fetch-*-Headern abgelehnt werden. Ein Bild auf https://evil.example, bei dem das Attribut „src“ eines img-Elements auf „https://site.example/foo.json“ gesetzt wurde führt dazu, dass der Browser den HTTP-Anfrage-Header &quot;Sec-Fetch-Site: Cross-site&quot; sendet.

Sec-Fetch-Site

Unterstützte Browser

  • Chrome: 76 <ph type="x-smartling-placeholder">
  • Edge: 79. <ph type="x-smartling-placeholder">
  • Firefox: 90. <ph type="x-smartling-placeholder">
  • Safari: 16.4 <ph type="x-smartling-placeholder">

Quelle

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 wurde
  • same-site, wenn die Anfrage von einer Subdomain Ihrer Website gestellt wurde (z.B. bar.site.example)
  • none, wenn die Anfrage explizit durch die Interaktion eines Nutzers mit dem User-Agent (z.B. Klicken auf ein Lesezeichen) verursacht wurde
  • cross-site, wenn die Anfrage von einer anderen Website (z.B. evil.example) gesendet wurde

Sec-Fetch-Mode

Unterstützte Browser

  • Chrome: 76 <ph type="x-smartling-placeholder">
  • Edge: 79. <ph type="x-smartling-placeholder">
  • Firefox: 90. <ph type="x-smartling-placeholder">
  • Safari: 16.4 <ph type="x-smartling-placeholder">

Quelle

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. Beispielsweise steht das Ziel navigate für eine Navigationsanfrage der obersten Ebene, während no-cors Ressourcenanfragen wie das Laden eines Bildes angibt.

Sec-Fetch-Dest

Unterstützte Browser

  • Chrome: 80 <ph type="x-smartling-placeholder">
  • Edge: 80. <ph type="x-smartling-placeholder">
  • Firefox: 90. <ph type="x-smartling-placeholder">
  • Safari: 16.4 <ph type="x-smartling-placeholder">

Quelle

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.

Abruf von Metadaten zum Schutz vor ursprungsü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 dieses Traffics werden gängige websiteübergreifende Sicherheitslücken wie CSRF, XSSI, Timing-Angriffe und ursprungsübergreifende Datenlecks abgeschwächt. Diese Richtlinie kann für alle Endpunkte Ihrer Anwendung aktiviert werden und erlaubt alle Ressourcenanfragen, die von Ihrer eigenen Anwendung kommen, sowie direkte Aufrufe (ü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 nicht alle Browser das Abrufen von Metadaten unterstützen, 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: Von derselben Website und vom Browser initiierte Anfragen zulassen

Alle Anfragen, die nicht aus einem ursprungsübergreifenden Kontext wie evil.example stammen, werden zugelassen. Dies sind insbesondere folgende Anfragen:

  • Sie stammen aus Ihrer eigenen Anwendung (z.B. eine Anfrage mit demselben Ursprung, bei der site.example-Anfragen site.example/foo.json immer zulässig sind).
  • Sie stammen von 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übergreifenden Traffic bestimmt 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 ursprungsübergreifend zugegriffen werden soll: Wenn Ihre Anwendung Endpunkte bereitstellt, für die CORS aktiviert ist, müssen Sie sie explizit von der Ressourcenisolierung deaktivieren, um sicherzustellen, dass websiteübergreifende Anfragen an diese Endpunkte weiterhin 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 Anfragen ablehnen, die websiteübergreifend und nicht zur Navigation dienen

Jede andere websiteübergreifende Anfrage wird von dieser Richtlinie zur Ressourcenisolierung abgelehnt und schützt Ihre Anwendung so vor gängigen websiteübergreifenden Angriffen.

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

  1. 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.
  2. Beheben Sie potenzielle Verstöße, indem Sie legitime ursprungsübergreifende Endpunkte ausnehmen.
  3. 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 Ihre Richtlinie bei Anwendung auf den Produktionstraffic protokolliert.

Unsere Erfahrung bei der Einführung einer Richtlinie zur Isolierung von Metadatenressourcen bei Google hat gezeigt, 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.

Richtlinie zur Ressourcenisolierung erzwingen

Nachdem Sie sich vergewissert haben, dass Ihre Richtlinie keine Auswirkungen auf legitimen Produktionstraffic hat, können Sie Einschränkungen durchsetzen. Damit stellen Sie sicher, dass andere Websites Ihre Ressourcen nicht anfordern können, und schützen Ihre Nutzer vor websiteübergreifenden Angriffen.

Weitere Informationen