CORS im HTTP verständlich erklärt: Cross-Origin Resource Sharing
CORS (Cross-Origin Resource Sharing) ist ein wichtiger Sicherheits-Mechanismus, der über HTTP-Header gesteuert wird. Er regelt, ob und wie Webanwendungen, die auf einer bestimmten Domain laufen (z. B. https://allerate.com), auf Ressourcen oder APIs einer anderen Domain (z. B. https://api.allerate.dev) zugreifen dürfen. CORS bricht somit die standardmässig im Browser aktive, sehr strenge Same-Origin-Policy (SOP) gezielt auf.
CORS ist damit kein Angriffsvektor, sondern eine kontrollierte Lockerung der Browser-Schutzregeln. Es greift nur im Browser-Kontext und ist von echten Sicherheits-Antwortheadern wie der Content-Security-Policy zu unterscheiden, die ein gänzlich anderes Schutzziel verfolgt.
Same-Origin-Policy (SOP) als Sicherheitsbasis
Ohne die Same-Origin-Policy wäre das Web extrem unsicher. Origin (Herkunft) definiert sich über die Kombination aus Protokoll (http/https), Domain und Port.
- Besuchen Sie eine bösartige Website, könnte diese sonst im Hintergrund ein JavaScript ausführen, das Ihre Session-Cookies ausliest und geheime Kontodaten von der API Ihrer Bank abruft.
- Die SOP verhindert dies: Sie blockiert jeden Versuch eines Skripts, Ressourcen von einer fremden Origin zu lesen.
CORS ist die kontrollierte Ausnahme von dieser Regel. Es teilt dem Browser über HTTP-Antwort-Header mit: „Ich kenne die anfragende Domain und erlaube ihr den Zugriff auf meine Daten.“
Die wichtigsten CORS-Header des Servers
Wenn ein Browser eine Cross-Origin-Anfrage stellt, prüft er die Antwort des Servers auf spezifische Header:
- Access-Control-Allow-Origin: Gibt an, welche Domains auf die API zugreifen dürfen.
- Sicher:
Access-Control-Allow-Origin: https://allerate.com - Unsicher (für geschützte APIs):
Access-Control-Allow-Origin: *(erlaubt jeder Website der Welt den Zugriff).
- Sicher:
- Access-Control-Allow-Methods: Listet die erlaubten HTTP-Methoden auf (z. B.
GET, POST, DELETE, OPTIONS). - Access-Control-Allow-Headers: Definiert, welche benutzerdefinierten Header der Client mitsenden darf (z. B.
Authorization,Content-Type). - Access-Control-Allow-Credentials: Teilt dem Browser mit, ob er sensible Anmeldeinformationen (wie Session-Cookies oder Authorization-Header) mitsenden darf (
trueoderfalse).
Der Ablauf: Einfache vs. Preflight-Anfragen
Der Browser unterscheidet bei CORS-Anfragen zwei Abläufe:
1. Einfache Anfragen (Simple Requests)
Bei einfachen Anfragen (z. B. ein normales GET- oder ein einfaches POST-Formular) sendet der Browser die Anfrage direkt ab. Nach Erhalt der Antwort prüft er, ob der Header Access-Control-Allow-Origin die Absenderdomain enthält. Wenn nicht, blockiert der Browser den Zugriff des JavaScripts auf die Antwortdaten (die Anfrage wurde auf dem Server dennoch ausgeführt!).
2. Preflight-Anfragen (OPTIONS)
Bei komplexeren Anfragen (z. B. POST-Anfragen mit JSON-Body und passendem Content-Type oder Anfragen mit Auth-Tokens) geht der Browser auf Nummer sicher. Er schaltet eine Preflight-Anfrage mit der HTTP-Methode OPTIONS vor:
sequenceDiagram
participant B as Browser
participant S as Webserver (API)
B->>S: 1. OPTIONS /api/data (Darf ich POST mit JSON senden?)
Note right of S: 2. Prüfe CORS-Regeln (erlaubt!)
S-->>B: 3. HTTP 200 OK + Access-Control-Allow-Origin
B->>S: 4. POST /api/data (tatsächlicher Request)
Note right of S: 5. Verarbeite Daten
S-->>B: 6. HTTP 200 OK + JSON-Daten
Erst wenn die Preflight-Anfrage (OPTIONS) vom Server mit den passenden Erlaubnis-Headern beantwortet wird, führt der Browser den tatsächlichen POST-Request aus. Dies schützt den Server vor unerwünschten Zustandsänderungen durch Fremdseiten.
Einfache vs. Preflight-Anfrage im Überblick
Ob der Browser eine Vorab-Anfrage (Preflight) schickt, hängt von Methode, Headern und Content-Type ab:
| Kriterium | Einfache Anfrage | Preflight (OPTIONS) |
|---|---|---|
| Methoden | GET, HEAD, einfaches POST | PUT, DELETE, PATCH |
| Content-Type | text/plain, form-urlencoded | application/json |
| Eigene Header | Keine | z. B. Authorization |
| Zusätzliche Anfrage | Nein | Ja, OPTIONS vorab |
Faustregel: Sobald Sie JSON senden oder einen Authorization-Header mitgeben, löst der Browser eine Preflight-Anfrage aus – der Server muss dann auch auf OPTIONS korrekt antworten.
Häufige CORS-Fehler und ihre Ursachen
Die meisten CORS-Probleme lassen sich auf wenige, wiederkehrende Fehlkonfigurationen zurückführen:
| Fehlermeldung / Symptom | Ursache | Lösung |
|---|---|---|
| «No ‘Access-Control-Allow-Origin’ header» | Server sendet den Header gar nicht | CORS serverseitig aktivieren |
Wildcard * trotz Cookies blockiert | Allow-Credentials: true + * | Konkrete Origin statt * setzen |
| Preflight schlägt mit 405 fehl | Server beantwortet OPTIONS nicht | OPTIONS-Route hinzufügen |
| Eigener Header wird abgelehnt | Header fehlt in Allow-Headers | Header explizit auflisten |
Praxisbeispiel: korrekte CORS-Antwort für eine geschützte API
Für eine API, die Cookies oder Tokens verarbeitet, muss der Server die konkrete Origin nennen und Credentials erlauben:
Access-Control-Allow-Origin: https://allerate.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400
Der Header Access-Control-Max-Age weist den Browser an, das Ergebnis der Preflight-Anfrage 24 Stunden zwischenzuspeichern. Das spart bei vielen API-Aufrufen unnötige OPTIONS-Anfragen und verbessert die Performance spürbar.
[!TIP] Fehlkonfigurationen bei CORS gehören zu den häufigsten Fehlern in der modernen Webentwicklung und blockieren oft die Kommunikation zwischen Frontend und Backend. Prüfen Sie die CORS- und HTTP-Header Ihrer APIs live mit dem HTTP Header Check auf balou.tools.
Häufig gestellte Fragen (FAQ)
Was ist die Same-Origin-Policy (SOP)?
SOP ist ein grundlegendes Sicherheitskonzept im Browser. Es verbietet Webseiten standardmässig, Skripte auszuführen, die Daten von einer anderen Domain abrufen (z. B. darf eine Schadseite keinen API-Request an Ihre Onlinebanking-Domain senden).
Darf man „Access-Control-Allow-Origin: *“ nutzen?
Für öffentliche APIs ohne Registrierung (wie Wetterdaten) ist dies in Ordnung. Für Systeme, die Authentifizierung (Cookies, JWTs) verlangen, ist der Wildcard-Eintrag `*` verboten. Es muss zwingend die konkrete Origin des Frontends deklariert werden.
Warum bekomme ich einen CORS-Fehler, obwohl der Server antwortet?
CORS ist eine reine Browser-Schutzmassnahme. Der Server führt die Anfrage oft aus und sendet eine Antwort, aber der Browser blockiert anschliessend den Zugriff des JavaScripts auf diese Antwort, weil der passende Access-Control-Allow-Origin-Header fehlt. Der Fehler erscheint deshalb nur im Browser, nicht in Werkzeugen wie curl oder Postman.
Löst die Wildcard * auch Anfragen mit Cookies?
Nein. Sobald Access-Control-Allow-Credentials auf true steht, verbietet die Spezifikation den Wildcard-Wert *. Der Server muss dann die konkrete Origin zurückgeben und sie bei mehreren erlaubten Domains dynamisch aus dem Origin-Request-Header spiegeln. Andernfalls blockiert der Browser die Antwort.