Lokal & kontrolliert
WISSEN · FÜR ALLE, DIE EINE WEBSITE BETREIBEN

CORS verstehen

Was die Regel der gleichen Herkunft schützt, was CORS davon lockert, wann der Browser vorher nachfragt und welche Freigaben gefährlich sind

Geprüft am 3. Oktober 2026 · etwa 7 Minuten Lesezeit

Kurz gesagt

Browser lassen eine Website die Antworten einer anderen nicht lesen — das ist die Regel der gleichen Herkunft. CORS ist die Ausnahme davon: Mit Access-Control-Allow-Origin erlaubt ein Server bestimmten fremden Seiten, seine Antworten zu lesen. Es schützt nichts, es öffnet etwas; halte jede Freigabe deshalb so eng wie möglich. Gefährlich wird es, wenn der Server jede anfragende Herkunft oder null zurückschreibt und zugleich Anmeldedaten zulässt. Und CORS hält nicht jede Anfrage auf: Formulare und einfache Abrufe kommen ohne Vorabanfrage beim Server an, deshalb braucht er einen eigenen Schutz gegen untergeschobene Aktionen.

Herkunft: Schema, Host und Port

Für den Browser gehört jede Antwort zu einer Herkunft (englisch Origin): Schema wie https, Hostname und Port. Nur wenn alle drei übereinstimmen, ist es dieselbe Herkunft; der Pfad zählt nicht. https://hexwarte.de/wissen/ und https://hexwarte.de/browser-einblick/ teilen sich eine Herkunft. http://hexwarte.de und https://tls.hexwarte.de:9443 haben jeweils eine andere.

Die Regel der gleichen Herkunft verbietet nicht alles. Links, Weiterleitungen und Formulare dürfen Anfragen an fremde Seiten schicken, Bilder, Skripte und Stile dürfen von dort eingebunden werden. Verboten ist in der Regel das Lesen: Ein Skript der einen Herkunft bekommt die Antwort einer anderen nicht zu sehen. Schon das Einbinden verrät aber manches, etwa die Maße eines Bildes. Die Grundidee erklärt auch der Begriff CORS (Cross-Origin Resource Sharing).

Was eine Freigabe lockert, und wann der Browser vorher fragt

Ruft ein Skript mit fetch() eine fremde Herkunft ab, schreibt der Browser die eigene Herkunft in die Kopfzeile Origin. Nennt die Antwort in Access-Control-Allow-Origin genau diese Herkunft oder einen Stern, bekommt das Skript sie, sonst nicht; den Grund nennt nur die Konsole der Entwicklerwerkzeuge. Entscheidend ist, wann die Anfrage beim Server ankommt:

  • Ohne Vorabanfrage: GET, HEAD und POST mit unverfänglichen Kopfzeilen, Inhalte nur als application/x-www-form-urlencoded, multipart/form-data oder text/plain — also, was auch ein HTML-Formular kann. Der Server führt die Anfrage aus; erst danach entscheidet der Browser, ob das Skript die Antwort lesen darf.
  • Mit Vorabanfrage (Preflight): andere Methoden wie PUT oder DELETE, eigene Kopfzeilen oder ein Inhaltstyp wie application/json. Der Browser fragt zuerst mit OPTIONS und schickt die eigentliche Anfrage nur, wenn Freigabe, Access-Control-Allow-Methods und Access-Control-Allow-Headers passen.
  • Das Ergebnis merkt er sich so lange, wie Access-Control-Max-Age sagt, ohne Angabe 5 Sekunden; Chromium-Browser wie Chrome und Edge höchstens zwei Stunden, Firefox höchstens 24 Stunden.
  • Von den Kopfzeilen der Antwort sieht das Skript nur einfache wie Content-Type, alle weiteren nur, wenn Access-Control-Expose-Headers sie nennt.

Anmeldedaten: warum der Stern dann nicht genügt

Cookies und andere Anmeldedaten schickt fetch() an fremde Herkünfte nur, wenn das Skript es ausdrücklich verlangt (credentials: 'include'). Antworten mit Anmeldedaten zu teilen, nennt der Fetch-Standard „im Allgemeinen ziemlich unsicher“ und stellt strengere Regeln auf:

  • Access-Control-Allow-Origin muss die anfragende Herkunft wörtlich nennen; ein Stern scheitert immer. Die Herkunft steht ohne Schrägstrich am Ende.
  • Access-Control-Allow-Credentials muss genau true lauten, kleingeschrieben.
  • Auch bei erlaubten Methoden, Kopfzeilen und sichtbar gemachten Kopfzeilen gilt der Stern dann nicht als Platzhalter; Authorization deckt er ohnehin nie ab.
  • Ob Cookies zu einer fremden Website überhaupt mitgehen, entscheiden zusätzlich SameSite und die Regeln des Browsers für Drittanbieter-Cookies, nicht die Freigabe.

Freigaben, die gefährlich sind

  • Die gespiegelte Herkunft: Der Server schreibt zurück, was in Origin stand, und erlaubt Anmeldedaten. Dann darf jede Seite im Namen angemeldeter Besucher lesen, soweit deren Browser die Cookies mitschickt — Kontodaten, Schlüssel, auch Kennungen, die vor untergeschobenen Anfragen schützen sollen. Und sie darf Anfragen schicken, die sonst an der Vorabanfrage scheitern würden.
  • Unsauber geprüfte Listen: Wer nur prüft, ob die Herkunft auf beispiel.example endet, lässt auch angreiferbeispiel.example durch; wer prüft, ob sie damit beginnt, auch beispiel.example.angreifer.example.
  • Die Herkunft null: Browser senden sie etwa aus Rahmen mit sandbox-Attribut, data:-Adressen, lokalen Dateien und nach Weiterleitungen über fremde Herkünfte. Jede Seite kann sie sich verschaffen.
  • Zu weites Vertrauen: Hat eine freigegebene Subdomain eine Cross-Site-Scripting (XSS)-Lücke oder läuft sie noch über unverschlüsseltes http, kann ein Angreifer über sie lesen.
  • Der Stern im internen Netz: Schützt nur eine Firewall oder die IP-Adresse eine Schnittstelle, macht er sie über die Browser im internen Netz für fremde Seiten lesbar.

CORS schützt nicht vor untergeschobenen Anfragen

Bei Cross-Site Request Forgery (CSRF) bringt eine fremde Seite deinen Browser dazu, eine Aktion bei einer Website auszulösen, bei der du angemeldet bist, etwa eine Bestellung. Die Antwort braucht der Angreifer nicht; die Anfrage selbst ist der Angriff. CORS hilft nicht, denn Formulare und einfache Abrufe kommen ohne Vorabanfrage an.

Die Abwehr liegt beim Server: eine Kennung im Formular, die eine fremde Seite nicht kennt (CSRF-Token), oder die Prüfung der Kopfzeile Sec-Fetch-Site. Darin gibt der Browser bei HTTPS-Adressen an, ob eine Anfrage von derselben Herkunft, derselben Website oder einer fremden kommt. Nimmt eine Schnittstelle nur application/json oder eine eigene Kopfzeile an, schickt der Browser einer fremden Seite die Anfrage erst nach einer Vorabanfrage — und nur, wenn die CORS-Freigabe diese Seite zulässt. SameSite bei den Cookie-Attributen ist eine zusätzliche Schicht, kein Ersatz; siehe Cookies einer Website sicher setzen.

Router und Geräte im Heimnetz

Weil CORS solche Anfragen nicht aufhält, konnten öffentliche Websites lange Router, Drucker oder Programme auf deinem Rechner ansprechen. Seit Chrome 142 (28. Oktober 2025) und Firefox 153 auf dem Desktop (21. Juli 2026) fragt der Browser vorher um Erlaubnis.

Nicht dasselbe: CORP, COEP und COOP

Drei Header mit ähnlichen Namen beantworten andere Fragen:

Vier Header, vier Fragen
Headergesetzt vonregelt
Access-Control-Allow-Origin (CORS)der Quellewelche fremde Herkunft die Antwort per Skript lesen darf
Cross-Origin-Resource-Policy (CORP)der Quelleob fremde Seiten sie überhaupt einbinden dürfen, etwa als Bild oder Skript; gegen Seitenkanal-Angriffe wie Spectre
Cross-Origin-Embedder-Policy (COEP)der einbindenden Seiteunter welchen Bedingungen sie fremde Inhalte lädt, etwa nur mit Zustimmung per CORP oder CORS
Cross-Origin-Opener-Policy (COOP)der Seite selbstob Fenster fremder Seiten, die sie öffnen oder die sie öffnet, auf sie zugreifen können

In der Header-Werkstatt stehen die drei unter „Einbettung und fremde Fenster“, CORS unter „Weitergabe von Daten“.

Ein Beispiel: Lenas Vereinsladen und der Messdienst von HexWarte

Lena betreut auch den Onlineladen ihres Sportvereins: die Seite auf https://www.vereinsladen.example, die Schnittstelle für Konto und Bestellungen auf https://api.vereinsladen.example, das Sitzungs-Cookie mit SameSite=None. Wegen eines CORS-Fehlers stellte ein Helfer den Server so ein, dass er jede Herkunft zurückschreibt und Anmeldedaten erlaubt. Seitdem geht auch das:

GET /api/konto HTTP/1.1
Host: api.vereinsladen.example
Origin: https://gewinnspiel.example
Cookie: sitzung=…

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://gewinnspiel.example
Access-Control-Allow-Credentials: true

Öffnet ein angemeldetes Mitglied die Gewinnspielseite in einem Browser, der Drittanbieter-Cookies zulässt, gibt es ihr ungewollt Name, Anschrift und Bestellungen preis. Richtig ist eine feste Liste, die nur https://www.vereinsladen.example enthält: Die Freigabe kommt nur bei genauer Übereinstimmung, dazu Vary: Origin. Dem Cookie genügt SameSite=Lax, denn www und api gehören zur selben Website. Für das Abschicken von Bestellungen braucht Lena zusätzlich einen Schutz gegen CSRF.

HexWarte braucht CORS an einer Stelle: Der Browser-Einblick auf hexwarte.de ruft seinen TLS-Messdienst unter tls.hexwarte.de, Port 9443, ab. Einem Abruf mit der fremden Herkunft https://beispiel.example antwortete er am 3. Oktober 2026 so (Auszug):

Access-Control-Allow-Origin: https://hexwarte.de
Vary: Origin
Cache-Control: no-store

Die Freigabe ist fest eingetragen, nicht gespiegelt. Anmeldedaten gibt es keine: Der Abruf geht ausdrücklich ohne Cookies, Access-Control-Allow-Credentials fehlt. Als einfacher GET-Abruf braucht er keine Vorabanfrage; OPTIONS lehnt der Messdienst mit 405 ab. Bei fester Freigabe rät der Fetch-Standard von Vary: Origin ab, MDN dazu; hier schadet es nicht, weil nichts zwischengespeichert wird.

Was du für eine enge Freigabe brauchst

  • Eine Liste der Adressen, die fremde Seiten wirklich lesen müssen; nur dort gehört eine Freigabe hin, nicht auf die ganze Domain.
  • Eine feste Liste vollständiger Herkünfte, Zeichen für Zeichen verglichen: keine Suche nach Wortteilen, keine selbst gebauten Muster, nie null.
  • Eine Entscheidung über Anmeldedaten. Für öffentliche Daten genügt ein Stern ohne Access-Control-Allow-Credentials; soll nichts geteilt werden, fehlen beide Kopfzeilen.
  • Vary: Origin, wo die Freigabe von der Anfrage abhängt. Sonst kann ein Zwischenspeicher eine Antwort mit fremder oder ohne Freigabe ausliefern, und erlaubte Abrufe scheitern.
  • Zwei Abrufe zum Gegenprüfen: Steht die fremde Herkunft in der Antwort, spiegelt der Server; steht dort null, lässt er null zu. Unter Windows heißt es curl.exe und NUL statt /dev/null (Antwort-Header richtig kopieren); Header setzen: Sicherheitsheader in nginx, Apache und Caddy setzen.
curl -sS -D - -o /dev/null -H "Origin: https://fremd.example" https://api.beispiel.example/konto
curl -sS -D - -o /dev/null -H "Origin: null" https://api.beispiel.example/konto

Was dieser Artikel nicht sagt

  • Der Artikel beschreibt nur, was Browser tun; wer etwa mit curl anfragt, ist an CORS nicht gebunden. Sensible Daten schützen allein Anmeldung und Rechteprüfung auf dem Server.
  • Ob ein Server die Herkunft spiegelt, zeigt eine einzelne Antwort nicht. Auch die Header-Werkstatt sieht nur den eingefügten Text und untersucht keine Vorabanfragen.
  • Browserangaben: Stand Oktober 2026. Ob Safari eine ähnliche Abfrage für das lokale Netz einführt, ist offen.
  • Gegen CSRF nennt der Artikel nur die Wege; die Umsetzung beschreibt das Merkblatt von OWASP in den Quellen.

Quellen

Geprüft am 3. Oktober 2026. Die Einordnung ist eine fachliche Bewertung, keine Rechtsberatung. Einen Fehler gefunden? Die Kontaktdaten stehen im Impressum.