33 Punkte von GN⁺ 2025-03-04 | 1 Kommentare | Auf WhatsApp teilen
  • Wenn man sich mit Cross-Site Requests beschäftigt, ist zunächst schwer nachzuvollziehen, warum sowohl CSRF-Schutz als auch CORS notwendig sind. Um das zu erklären, braucht es jedoch einige Begriffe.

CSRF und CORS

  • CSRF (Cross-Site Request Forgery)
    • Früher war das häufig, heute ist es dank standardmäßigem Schutz in den meisten Web-Frameworks kaum noch ein Problem
    • Angriffsweise: Der Nutzer wird dazu gebracht, auf einer bösartigen Website ein bestimmtes Formular anzuklicken, sodass ein Cross-Site-Request gesendet wird
    • Abwehr: Prüfen, ob die Anfrage nicht von einer fremden Website stammt
  • CORS (Cross-Origin Resource Sharing)
    • Teil der HTTP-Spezifikation, der definiert, wie bestimmte Cross-Site-Requests erlaubt werden können
    • Mit Preflight-Anfragen und Response-Headern wird festgelegt, von welchen Origins Anfragen gesendet werden dürfen

Heißt das also, dass Cross-Site-Requests standardmäßig erlaubt sind und man deshalb CSRF-Schutz braucht? Oder sind sie standardmäßig blockiert und man braucht CORS, um sie zu erlauben? Die Antwort lautet: beides.

Standardverhalten

  • Same-Origin-Policy
    • Eine vom Browser erzwungene Sicherheitsrichtlinie
    • Im Allgemeinen gilt: Cross-Site-Schreiben (Write) ist erlaubt, Lesen (Read) ist verboten
    • Der Browser erlaubt zum Beispiel POST-Anfragen über Formulare, aber die Antwort kann nicht gelesen werden
  • SameSite-Cookie-Richtlinie
    • 2019 wurde das Standardverhalten von Cookies geändert
    • Früher wurden Cookies auch bei Cross-Site-Requests immer mitgesendet
    • Das neue Attribut SameSite wurde eingeführt, und der Standardwert wurde auf Lax geändert
    • Stand 2025 unterstützen 96 % der Browser das Attribut SameSite, 75 % den neuen Standardwert (Lax)
    • Safari setzt dies jedoch nicht standardmäßig um, und UCBrowser unterstützt es weiterhin nicht
  • Unterschied zwischen Site und Origin
    • Origin: Kombination aus Protokoll + Hostname + Port
    • Site: Kombination aus Protokoll + Top-Level-Domain + 1 (Subdomains und Ports werden ignoriert)

CORS

  • CORS ist eine Möglichkeit, Ausnahmen von der Same-Origin-Policy für bestimmte Origins zuzulassen
  • Bevor der Browser eine Anfrage sendet, schickt er eine OPTIONS-Anfrage als Preflight-Request
  • Der Server definiert die Zulassungsregeln über Response-Header (mit Access-Control-*-Headern)
  • Für folgende Anfragetypen gilt CORS:
    • fetch und XMLHttpRequest
    • Web-Fonts
    • WebGL-Texturen
    • Bild-/Videoframes, die in canvas mit drawImage gezeichnet werden
    • Bilder, die in der CSS-Eigenschaft shape-outside verwendet werden
  • Formularübermittlungen sind jedoch eine Ausnahme, für sie gilt CORS nicht
    • Das HTML-4.0-Tag <form> erlaubt schon sehr lange Cross-Site-Requests
    • Daher mussten bestehende Server bereits so entworfen sein, dass sie sich gegen CSRF-Angriffe schützen
    • Damit die Antwort geteilt werden darf, muss der Server Access-Control-Allow-Origin setzen, aber die Anfrage selbst wird auch ohne Preflight akzeptiert

Frage: Wie bleibt dieses Vorgehen mit der SameSite-Richtlinie konsistent?

Methoden zum CSRF-Schutz

  • Cross-Site-Schreibanfragen sind erlaubt, die Antwort wird aber nicht geteilt
    • Die meisten Websites möchten Cross-Site-Schreibzugriffe nicht zulassen
  • Standardmäßige CSRF-Abwehr
    • Ein benutzerspezifisches CSRF-Token wird in die Anfrage aufgenommen und validiert
    • Vorgehensweise:
      • Formularübermittlung: Token als verstecktes Eingabefeld (hidden input) hinzufügen
      • JS-Anfragen: In einem Cookie oder meta-Tag speichern und dann in Headern oder Parametern mitsenden
  • JS-Anfragen sind ursprünglich Cross-Site standardmäßig blockiert
    • Innerhalb derselben Site sind sie jedoch erlaubt
    • Mit einem CSRF-Token lässt sich jede Anfrage nach demselben Schema validieren
  • Zusätzlicher Sicherheitsvorteil
    • Das Verfahren setzt voraus, dass der Browser das Lesen von Antworten standardmäßig blockiert
    • Das ist sicherer, als nur den Origin-Header zu prüfen

Frage: Warum wechseln manche Frameworks CSRF-Tokens regelmäßig?

Die Rolle des Browsers

  • Der Kern der Web-Sicherheit hängt davon ab, ob dem Browser vertraut werden kann
  • Der Browser:
    • erzwingt die Same-Origin-Policy
    • blockiert das Lesen von Antworten, wenn es nicht erlaubt ist
    • entscheidet, ob SameSite=Lax als Standard angewendet wird
    • implementiert CORS und sendet sichere Preflight-Anfragen

Wir müssen dem verwendeten Browser vertrauen.

Fazit

  • Wenn SameSite=Lax in 100 % der Browser unterstützt würde, wäre die Sicherheit höher,
    aktuell gibt es jedoch weiterhin die Ausnahme, dass Cross-Site-POST-Anfragen erlaubt sind
  • Daher sollten Entwickler CSRF-Schutz weiterhin berücksichtigen

„Das Internet wird immer sicherer, aber zugleich nimmt die Kompatibilität mit der Vergangenheit immer weiter ab.“

Quelle

  1. Same-origin policy
  2. caniuse SameSite cookie attribute
  3. OWASP CSRF cheatsheet
  4. CORS wiki with requirements
  5. CORS spec
  6. CORS on MDN
  7. Preflight request
  8. Origin request header
  9. Origin and Site

1 Kommentare

 
GN⁺ 2025-03-04
Hacker-News-Kommentare
  • CORS ist ein Mechanismus, mit dem der Server dem Browser explizit mitteilt, welche Cross-Origin-Anfragen die Antwort lesen dürfen

    • Standardmäßig blockiert der Browser, dass ein Cross-Origin-Skript die Antwort liest
    • Wenn es nicht ausdrücklich erlaubt ist, kann die anfragende Domain die Antwort nicht lesen
    • Zum Beispiel könnte ein Skript von evil.com eine Anfrage an bank.com/transactions senden, um die Transaktionshistorie des Opfers zu lesen
    • Der Browser erlaubt, dass die Anfrage bank.com erreicht, blockiert aber, dass evil.com die Antwort liest
  • CSRF-Schutz verhindert, dass bösartige Cross-Origin-Anfragen im Namen eines authentifizierten Nutzers unbefugt Aktionen ausführen

    • Zum Beispiel könnte ein Skript von evil.com eine Anfrage senden, um auf bank.com eine Aktion auszuführen (z. B. Geld an bank.com/transfer?from=victim&to=hacker zu überweisen)
    • Der serverseitige CSRF-Schutz von bank.com weist dies zurück (wahrscheinlich, weil die Anfrage keinen geheimen CSRF-Token enthält)
  • Beim CSRF-Schutz geht es um Schreibschutz, bei CORS um Leseschutz

  • Durch JS ausgelöste Anfragen sind standardmäßig nicht Cross-Site erlaubt

    • Mit fetch() kann man Cross-Site-Anfragen initiieren, wenn nur erlaubte Header verwendet werden
  • Es scheint eine bessere Erklärung zu diesem Thema zu geben

    • Link zu einem relevanten Blog bereitgestellt
  • Antwort auf die Frage im Blogbeitrag

    • Das <form>-Element aus HTML 4.0 kann einfache Anfragen an jede Origin absenden
    • Es gab eine Frage dazu, wie das mit der SameSite-Initiative zusammenpasst
  • 2022 wurde dem MDN-Artikel zu CORS ein Absatz hinzugefügt, um die Herkunft des Begriffs „einfache Anfrage“ klarzustellen

    • Zuvor stand dort nur, dass er in der Fetch-Spezifikation nicht erwähnt werde
    • 2019 fehlte ein Hinweis auf CSRF-Schutzmechanismen von Browsern in Fällen, in denen SameSite=Lax unterstützt oder als Standard gesetzt war
  • Es ist verwirrend, dass SameSite unabhängig von CORS-Preflight hinzugefügt wurde

    • Es wird gefragt, warum Browserhersteller nicht für alle Cross-Origin-POST-Anfragen einen Preflight verlangt haben
  • Man könnte denken, dass es auch ohne csrf sicher ist, aber einige Bibliotheken (z. B. django rest framework) können HTML-Formulare verarbeiten, wenn der Content-Type-Header gesetzt ist

    • Dadurch kann jemand ein Formular auf der Website des Nutzers posten und so Anfragen in dessen Namen senden
  • Frage dazu, warum CSRF-Tokens rotiert werden

    • OWASP sagt, das sei sicherer, aber der Grund ist nicht ganz klar
  • Gewünscht wird ein Flussdiagramm für dieses komplexe Thema

    • Es wird eine neue Anwendungsplattform und ein neuer Satz von Standards gewünscht
  • Diese Dinge unterstützen keine einfache Diagnose-Nachverfolgung

    • Mehrfach wurden intransparente Fehler bei legitimen Anwendungsfällen erlebt, die nicht korrekt konfiguriert waren
  • Vor dem Aufkommen von CORS war nicht klar, warum man Anfragen an beliebige Endpunkte senden konnte, die nicht zur Seiten-Origin gehörten, die Antworten aber nicht sehen konnte

    • Es wird gefragt, ob das zufällig in die Spezifikation geraten ist, absichtlich im Hinblick auf XSS so gestaltet wurde oder ob ein führender Browser das so implementierte und andere Browser nachzogen
  • Verwirrung über CSRF-Schutz

    • Es wird gefragt, was einen Angreifer daran hindert, einen CSRF-Token von goodsite.com zu holen, ihn in badsite.com einzubauen und Alice dazu zu bringen, von badsite.com aus eine Anfrage an goodsite.com abzusenden