Wir alle kennen das: Man sendet eine API-Anfrage, wartet auf die Antwort und plötzlich erscheint in der Browserkonsole die Meldung „CORS-Fehler“.
Für viele Entwickler besteht der erste Instinkt darin, eine schnelle Lösung zu finden: Access-Control-Allow-Origin: * hinzufügen und weitermachen. Dieser Ansatz geht jedoch völlig am Ziel vorbei. CORS ist nicht nur eine weitere Konfigurationshürde, sondern einer der wichtigsten Sicherheitsmechanismen, die jemals für Browser entwickelt wurden.
CORS(Cross-Origin Resource Sharing) dient dem Schutz der Benutzer und ermöglicht gleichzeitig die legitime domänenübergreifende Kommunikation zwischen Webanwendungen. Dennoch wird es oft missverstanden, falsch konfiguriert oder wie ein Bug behandelt, den es zu „umgehen“ gilt.
Aber jetzt nicht mehr.
In diesem Leitfaden gehen wir über die Grundlagen hinaus. Sie lernen:
- Warum CORS existiert und wie es sich aus der Same-Origin Policy (SOP) entwickelt hat
- Wie Browser und Server tatsächlich den Cross-Origin-Zugriff aushandeln
- Was führt dazu, dass manche CORS-Konfigurationen fehlschlagen, obwohl sie „richtig aussehen“?
- Sichere Handhabung von Preflight-Anfragen, Anmeldedaten und Browser-Eigenheiten
Am Ende wissen Sie nicht nur, wie Sie CORS konfigurieren, sondern verstehen auch, warum es sich so verhält, wie es sich verhält, und wie Sie Ihre APIs sicher darauf abstimmen können.
Was ist CORS (und warum gibt es das?)
CORS ist ein Sicherheitsstandard für Browser, der festlegt, wie Webanwendungen von einer Quelle sicher auf Ressourcen einer anderen Quelle zugreifen können.
Um die CORS-Sicherheit zu verstehen, müssen Sie zunächst wissen, warum sie geschaffen wurde.
Lange bevor APIs und Microservices das Web eroberten, folgten Browser einer einfachen Regel, die als Same-Origin Policy (SOP) bezeichnet wurde.
Diese Richtlinie besagte, dass eine Webseite nur Daten von derselben Quelle senden und empfangen durfte, d. h. vom selben Protokoll, derselben Domain und demselben Port.
Zum Beispiel:
Diese Einschränkung war in den Anfängen des Internets, als die meisten Websites monolithisch waren, durchaus sinnvoll. Eine einzelne Website hostete ihr Frontend, Backend und ihre Assets unter einer einzigen Domain.
Mit der Weiterentwicklung des Internets durch APIs, Microservices und Integrationen von Drittanbietern wurde diese Regel jedoch zu einem Hindernis. Entwickler benötigten Frontend-Anwendungen, um mit anderen Domänen zu kommunizieren, beispielsweise:
- www.example.com, der mit api.example.com kommuniziert
- Ihre App, die eine Verbindung zu einem CDN oder einem Analyse-Endpunkt herstellt
- Web-Clients, die APIs von Drittanbietern (wie Stripe oder Google Maps) aufrufen
Die Same-Origin-Policy wurde zu einer Barriere, die moderne, verteilte Architekturen blockierte.
Hier kam Cross-Origin Resource Sharing (CORS) ins Spiel.
Anstatt die Browser-Einschränkungen vollständig aufzuheben, führte CORS eine kontrollierte Lockerung der SOP ein. Damit wurde eine sichere Möglichkeit für Browser und Server geschaffen, domänenübergreifend zu kommunizieren – und zwar sicher und nur, wenn beide Seiten zustimmen.
Stellen Sie sich das so vor: SOP ist eine verschlossene Tür, die niemanden hereinlässt, und CORS ist dieselbe Tür, aber mit einer Gästeliste und einem Türsteher, der die Ausweise kontrolliert.
Dieses Gleichgewicht zwischen Flexibilität und Schutz macht die CORS-Konfiguration für jede moderne Webanwendung so wichtig.
Die Same-Origin-Policy (SOP) verstehen
Bevor wir uns näher mit der CORS-Konfiguration befassen, ist es wichtig, deren Grundlage zu verstehen: die Same-Origin Policy (SOP).
Wie bereits erwähnt, ist SOP die erste Verteidigungslinie des Browsers gegen böswilliges Verhalten im Internet. Es verhindert, dass eine Website frei auf die Daten einer anderen Website zugreifen kann, wodurch sensible Informationen wie Cookies, Authentifizierungstoken oder persönliche Daten offengelegt werden könnten.
So funktioniert es in der Praxis: Wenn eine Webseite in Ihrem Browser geladen wird, wird ihr anhand von drei Elementen eine Herkunft zugewiesen: dem Protokoll, dem Host und dem Port:
https:// api.example.com :443
^ ^ ^
Protokoll Host Port
Zwei URLs gelten nur dann als gleicher Ursprung, wenn alle drei Teile übereinstimmen. Andernfalls behandelt der Browser sie als unterschiedlichen Ursprung.
Diese einfache Regel verhindert schädliche Cross-Site-Aktionen. Ohne sie könnte eine beliebige Website Ihr Online-Banking-Dashboard in einem unsichtbaren Frame laden, Ihren Kontostand auslesen und ihn ohne Ihre Zustimmung an einen Angreifer senden.
Kurz gesagt dient SOP dazu, Inhalte zwischen verschiedenen Websites zu isolieren und sicherzustellen, dass jede Quelle eine in sich geschlossene Sicherheitszone ist.
Warum SOP allein nicht ausreichte
Die Same-Origin-Policy funktionierte perfekt, als Websites noch in sich geschlossen waren. Mit der Entwicklung des Webs zu einem Ökosystem aus APIs, Microservices und verteilten Architekturen wurde diese strenge Regel jedoch zu einer erheblichen Einschränkung.
Moderne Anwendungen müssen:
- Rufen Sie ihre eigenen APIs auf, die auf verschiedenen Subdomains gehostet werden (app.example.com → api.example.com).
- Assets von CDNs oder Drittanbieterdiensten abrufen
- Integration mit externen APIs wie Stripe, Firebase oder Google Maps
Unter SOP wurden diese legitimen Cross-Origin-Anfragen blockiert. Entwickler versuchten alle möglichen Workarounds, darunter JSONP, Reverse-Proxys oder doppelte Domains, aber diese Lösungen waren entweder unsicher oder äußerst komplex.
Hier hat CORS (Cross-Origin Resource Sharing) die Spielregeln verändert.
CORS führte ein Handshake-System ein, das es Browsern und Servern ermöglichte, Vertrauen auszuhandeln. Anstatt SOP zu brechen, erweiterte es dieses und bot eine Möglichkeit, bestimmte Ursprünge für die domänenübergreifende Kommunikation sicher auf die Whitelist zu setzen.
So funktioniert CORS: Der Ablauf auf Protokollebene
Wie bereits erwähnt, sendet Ihr Browser eine Anfrage an eine andere Quelle nicht einfach blindlings. Stattdessen folgt er einem genau definierten CORS-Protokoll: einem Hin- und Her-Dialog zwischen Browser und Server, um zu bestimmen, ob die Anfrage zugelassen werden soll.
Im Kern funktioniert CORS über HTTP-Header. Der Browser fügt jeder Cross-Origin-Anfrage einen Origin-Header hinzu, der dem Server mitteilt, woher die Anfrage stammt. Der Server antwortet dann mit einem oder mehreren Access-Control-*Headern, die festlegen, was erlaubt ist.
Hier ist ein vereinfachtes Beispiel für dieses Gespräch:
# Request
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
# Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json
{"message": "Success"}
In diesem Fall erlaubt der Server dem Ursprungshttps://app.example.com ausdrücklich den Zugriff auf seine Ressource. Der Browser überprüft diese Antwort, bestätigt die Übereinstimmung und liefert die Daten an Ihr JavaScript.
Wenn jedoch die Ursprünge nicht übereinstimmen oder die Antwort-Header fehlen oder falsch sind, blockiert der Browser die Antwort stillschweigend. Sie sehen die Daten nicht, sondern nur die frustrierende Meldung „CORS-Fehler“ in Ihrer Konsole.
Es ist wichtig zu beachten, dass CORS einen Server nicht von sich aus sicherer macht. Stattdessen erzwingt es Regeln für die Interaktion zwischen Browsern und Servern, eine Sicherheitsschicht, die sicherstellt, dass nur vertrauenswürdige Quellen auf geschützte Ressourcen zugreifen können.
Arten von CORS-Anfragen
CORS definiert zwei Haupttypen von Anfragen: einfache und vorab geprüfte. Der Unterschied liegt darin, wie viel Überprüfung der Browser vor dem Senden von Daten durchführt.
1. Einfache Anfragen
Eine einfache Anfrage ist die unkomplizierteste Art. Sie wird von Browsern automatisch zugelassen, solange sie bestimmte Regeln befolgt:
- Verwendet eine der folgenden Methoden: GET, HEAD oder POST
- Enthält nur bestimmte Kopfzeilen:
- Akzeptieren
- Akzeptierte Sprachen
- Sprache des Inhalts
- Content-Type (aber nur application/x-www-form-urlencoded, multipart/form-data oder text/plain)
- Verwendet keine benutzerdefinierten Header oder Streams.
So sieht es aus:
# Request
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
# Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json
{"message": "This is the response data"}In diesem Fall:
- Der Browser fügt automatisch den Origin-Header hinzu.
- Der Server muss Access-Control-Allow-Origin mit einem übereinstimmenden Ursprung zurückgeben.
- Wenn die Herkunft nicht übereinstimmt oder fehlt, blockiert der Browser die Antwort.
2. Vorfluganfragen
Bei komplexeren Anfragen wird es interessanter. Beispielsweise wenn Sie Methoden wie PUT, DELETE oder benutzerdefinierte Header wie Authorization verwenden.
Bevor die eigentliche Anfrage gesendet wird, führt der Browser eine Vorabprüfung mithilfe einer OPTIONS-Anfrage durch. Dieser Schritt stellt sicher, dass der Server den beabsichtigten Vorgang ausdrücklich zulässt.
Hier ein Beispiel:
# Preflight Request
OPTIONS /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type, authorization
# Preflight Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: PUT, POST, GET, DELETE
Access-Control-Allow-Headers: content-type, authorization
Access-Control-Max-Age: 3600
# Actual Request (only sent if preflight succeeds)
PUT /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Content-Type: application/json
Authorization: Bearer token123
{"data": "update this resource"}In dieser Sequenz:
- Der Browser erkennt eine nicht einfache Anfrage.
- Es sendet eine Preflight-OPTIONS-Anfrage und bittet um die Erlaubnis für die eigentliche Methode und die Header.
- Der Server antwortet mit den Methoden, Headern und Ursprüngen, die er zulässt.
- Wenn die Vorabprüfung erfolgreich ist, sendet der Browser die eigentliche Anfrage. Andernfalls blockiert er sie.
Umgang mit Anmeldedaten in CORS
Bei APIs, die eine Authentifizierung wie Cookies, Tokens oder sitzungsbasierte Anmeldungen erfordern, verhält sich CORS anders.
Standardmäßig behandeln Browser Cross-Origin-Anfragen aus Sicherheitsgründen als nicht authentifiziert. Das bedeutet, dass Cookies oder HTTP-Authentifizierungsheader nicht automatisch enthalten sind.
Um Anfragen mit Anmeldedaten sicher zu ermöglichen, müssen zwei wichtige Schritte aufeinander abgestimmt werden:
1. Der Client muss Anmeldeinformationen ausdrücklich zulassen:
fetch('https://api.example.com/data', {
credentials: 'include'
})2. Der Server muss sie ausdrücklich zulassen:
Zugriffskontrolle – Zulässige Anmeldedaten: true
Aber es gibt einen Haken, und zwar einen großen.
Wenn Access-Control-Allow-Credentials auf „true“ gesetzt ist, können Sie in Access-Control-Allow-Origin keine Platzhalter (*) verwenden. Browser lehnen die Antwort ab, wenn Sie dies versuchen.
Das liegt daran, dass die Zulassung von Anfragen mit Anmeldedaten aus allen Quellen den gesamten Zweck der CORS-Sicherheit zunichte machen würde, da dadurch jede Website im Internet auf private Daten zugreifen könnte, die mit der Sitzung eines Benutzers verknüpft sind.
Also stattdessen:
Zugriffskontrolle – Herkunft zulassen: *
Access-Control-Allow-Credentials: trueSie sollten immer einen bestimmten Ursprung verwenden:
Access-Control-Allow-Origin: https://yourapp.com
Access-Control-Allow-Credentials: trueWenn Ihre API mehrere vertrauenswürdige Domänen bedient, können Sie den richtigen Ursprungsheader dynamisch auf der Serverseite zurückgeben:
const allowedOrigins = ['https://app1.com', 'https://app2.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}Dieser Ansatz stellt sicher, dass Ihre authentifizierten Anfragen sicher und beabsichtigt bleiben und nicht für jeden zugänglich sind, der es versucht.
Wie Browser bestimmen, welche Anfragen CORS-berechtigt sind
Noch bevor eine Anfrage Ihren Server erreicht, entscheidet der Browser, ob sie unter die CORS-Regeln fällt.
Diese Entscheidung hängt davon ab, woher die Anfrage kommt und ob sie auf eine andere Domain, einen anderen Port oder ein anderes Protokoll abzielt.
Zum Beispiel:
- Anforderung von https://api.example.com von einer Seite, die unter https://example.com bereitgestellt wird: ✅ CORS gilt (unterschiedliche Subdomain).
- Anfrage „https://example.com:3000“ von „https://example.com“: ✅ CORS gilt (anderer Port).
- Anfrage von https://example.com von derselben Domain und demselben Port: ❌ CORS gilt nicht.
Wenn der Browser feststellt, dass eine Anfrage verschiedene Ursprünge hat, fügt er automatisch den Origin-Header in die Anfrage ein:
Quelle: https://example.com
Dieser Header teilt dem Server mit, woher die Anfrage stammt, und dient dem Server als Grundlage für die Entscheidung, ob der Zugriff zugelassen oder blockiert wird.
Wenn die Antwort nicht die richtigen Header enthält (wie Access-Control-Allow-Origin), blockiert der Browser einfach den Zugriff auf die Antwort, obwohl der Server technisch gesehen eine Antwort gesendet hat.
Das ist ein wichtiger Unterschied: Der Browser erzwingt CORS, nicht der Server.
Interne Sicherheitsprüfungen, XMLHttpRequest vs. Fetch und Browserunterschiede
Nicht alle Browser behandeln CORS auf die gleiche Weise, aber sie alle folgen dem gleichen Sicherheitsmodell: Vertraue niemals Cross-Origin-Daten, es sei denn, dies ist ausdrücklich erlaubt.
Der Unterschied besteht darin, wie streng sie die Regeln durchsetzen und auf welche APIs sie diese anwenden.
1. Die interne CORS-Sicherheitsprüfung
Wenn ein Browser eine Antwort auf eine Cross-Origin-Anfrage erhält, führt er einen internen Validierungsschritt durch, bevor er die Antwort Ihrem JavaScript-Code zur Verfügung stellt.
Es überprüft auf Header wie:
- Access-Control-Allow-Origin: muss mit der anfragenden Herkunft übereinstimmen (oder in einigen Fällen * sein).
- Access-Control-Allow-Credentials: muss wahr sein, wenn Cookies oder Authentifizierungstoken beteiligt sind.
- Access-Control-Allow-Methods und Access-Control-Allow-Headers: müssen mit der ursprünglichen Preflight-Anfrage übereinstimmen, falls eine solche gesendet wurde.
Wenn eine dieser Überprüfungen fehlschlägt, löst der Browser keinen HTTP-Fehler aus, sondern blockiert lediglich den Zugriff auf die Antwort und protokolliert einen CORS-Fehler in der Konsole.
Dies erschwert die Fehlersuche, da die eigentliche Netzwerkanfrage zwar erfolgreich war, der Browser das Ergebnis jedoch aus Sicherheitsgründen verbirgt.
2. XMLHttpRequest vs. Fetch
Sowohl XMLHttpRequest als auch die moderne fetch()-API unterstützen CORS, verhalten sich jedoch hinsichtlich Anmeldeinformationen und Standardeinstellungen etwas unterschiedlich.
Mit XMLHttpRequest:
- Cookies und HTTP-Authentifizierung werden automatisch gesendet, wenn „withCredentials“ auf „true“ gesetzt ist.
- Das Verhalten vor dem Flug hängt davon ab, ob benutzerdefinierte Header hinzugefügt werden.
Mit Fetch:
- Anmeldedaten (Cookies, HTTP-Authentifizierung) sind standardmäßig nicht enthalten.
- Sie müssen sie explizit aktivieren, indem Sie Folgendes verwenden:
fetch("https://api.example.com/data", {
credentials: "include"
});- fetch behandelt auch Weiterleitungen unter CORS strenger, da es keine Cross-Origin-Weiterleitungen verfolgt, sofern diese nicht erlaubt sind.
Fetch ist zwar sauberer und moderner, aber auch weniger nachsichtig, wenn Sie einen Header vergessen oder eine Anmeldeinformationsregel übersehen.
3. Unterschiede und Eigenheiten der Browser
Obwohl die CORS-Spezifikation ein Standard ist, implementieren Browser sie mit geringfügigen Unterschieden:
- Safari kann bei Cookies und Anfragen mit Anmeldedaten übermäßig streng sein, insbesondere wenn Cookies von Drittanbietern blockiert werden.
- Firefox speichert manchmal fehlgeschlagene Preflight-Antworten länger als erwartet im Cache, was zu inkonsistenten Ergebnissen während des Tests führt.
- Chrome wendet CORS bei bestimmten Weiterleitungsketten strenger an als bei anderen.
Aufgrund dieser Unterschiede kann eine Konfiguration, die in einem Browser einwandfrei funktioniert, in einem anderen Browser unbemerkt fehlschlagen.
Aus diesem Grund ist es unerlässlich, CORS-Einstellungen in verschiedenen Browsern zu testen, insbesondere wenn Anmeldedaten oder Weiterleitungen beteiligt sind.
Serverseitige Verarbeitung des Origin-Headers
Während der Browser CORS durchsetzt, findet die eigentliche Entscheidungsfindung auf dem Server statt.
Wenn der Browser eine Cross-Origin-Anfrage sendet, enthält diese immer den Origin-Header. Die Aufgabe des Servers besteht darin, diesen Header zu überprüfen, zu entscheiden, ob er zugelassen wird, und als Antwort die richtigen CORS-Header zurückzugeben.
1. Überprüfung der Herkunft
Eine typische Anfrage könnte wie folgt aussehen: Herkunft: https://frontend.example.com
Auf dem Server muss Ihr Code überprüfen, ob diese Herkunft zulässig ist. Der einfachste (und sicherste) Ansatz besteht darin, eine Zulassungsliste vertrauenswürdiger Domänen zu führen:
const allowedOrigins = ["https://frontend.example.com", "https://admin.example.com"];
if (allowedOrigins.includes(req.headers.origin)) {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
}Dadurch wird sichergestellt, dass nur bekannte Clients auf Ihre API zugreifen können, während andere keine CORS-Berechtigung erhalten.
Vermeiden Sie die Rückgabe von „Access-Control-Allow-Origin: *“, wenn Ihre API Cookies, Tokens oder andere Anmeldedaten verarbeitet.
2. Bearbeitung von Preflight-Anfragen
Bei OPTIONS-Preflight-Anfragen muss der Server mit derselben Sorgfalt antworten wie bei Hauptanfragen.
Eine vollständige Preflight-Antwort umfasst:
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400Diese Header teilen dem Browser mit, was erlaubt ist und wie lange er diese Entscheidung zwischenspeichern darf. Wenn einer davon fehlt oder falsch ist, blockiert der Browser die Folgeanfrage, selbst wenn Ihr Endpunkt selbst einwandfrei funktioniert.
3. Dynamisches Setzen von CORS-Headern
In großen Systemen (wie Multi-Tenant-Plattformen oder APIs mit mehreren Clients) müssen die zulässigen Ursprünge möglicherweise dynamisch sein.
Zum Beispiel:
const origin = req.headers.origin;
if (origin && origin.endsWith(".trustedclient.com")) {
res.setHeader("Access-Control-Allow-Origin", origin);
}Dieses Muster lässt alle Subdomains einer vertrauenswürdigen Domain zu, filtert aber trotzdem unbekannte Quellen raus.
Stellen Sie einfach sicher, dass Sie die Herkunft sorgfältig überprüfen und keine String-Übereinstimmungen mit Benutzereingaben ohne Einschränkungen vornehmen, da Angreifer sonst Header fälschen könnten, die gültig aussehen.
4. Warum „Es funktioniert in Postman“ nicht bedeutet, dass es richtig konfiguriert ist
Eines der größten Missverständnisse in Bezug auf CORS lautet: „Es funktioniert in Postman, also muss es ein Browserproblem sein.“
Postman erzwingt CORS überhaupt nicht, da es kein Browser ist.
Das bedeutet, dass selbst eine vollständig offene API ohne Access-Control-* Header dort einwandfrei funktioniert, in Chrome oder Firefox jedoch sofort fehlschlägt.
Wenn Ihre API also in Postman funktioniert, aber nicht in Ihrer Web-App, sind Ihre CORS-Header wahrscheinlich unvollständig oder falsch konfiguriert.
Häufige CORS-Fehlkonfigurationen (und wie man sie vermeidet)
1. Verwendung von Access-Control-Allow-Origin: * mit Anmeldeinformationen
Dies ist der häufigste und gefährlichste Fehler.
Wenn Ihre Antwort beides enthält:
Zugriffskontrolle – Herkunft zulassen: *
Access-Control-Allow-Credentials: true…der Browser blockiert die Anfrage automatisch.
Die CORS-Spezifikation verbietet die Verwendung von Platzhaltern, wenn Anmeldedaten enthalten sind, da dadurch jede Website auf Benutzerdaten zugreifen könnte, die mit Cookies oder Authentifizierungstoken verknüpft sind.
Behebung: Bei Verwendung von Anmeldeinformationen immer einen bestimmten Ursprung zurückgeben:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true2. Vergessen, Preflight-Anfragen zu bearbeiten
Viele APIs reagieren korrekt auf GET- und POST-Anfragen, vergessen jedoch die OPTIONS-Preflight-Anfrage.
In diesem Fall erreicht der Browser niemals Ihren tatsächlichen Endpunkt und blockiert die Hauptanfrage nach dem fehlgeschlagenen Preflight.
Behebung: OPTIONS-Anfragen explizit behandeln und mit den richtigen Headern antworten:
if (req.method === "OPTIONS") {
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
return res.sendStatus(204);
}3. Nicht übereinstimmende Anfrage- und Antwort-Header
Ein weiteres subtiles Problem: Ihre Preflight-Anfrage fordert möglicherweise bestimmte Header an, aber der Server erlaubt diese nicht explizit.
Wenn Ihre Anfrage beispielsweise Folgendes enthält:
Zugriffskontroll-Anforderungs-Header: Autorisierung, Inhaltstyp
…aber der Server antwortet nur mit:
Zugriffskontrolle – Zulässige Header: Inhaltstyp
…der Browser blockiert es. Beide Listen müssen exakt übereinstimmen.
Behebung: Stellen Sie sicher, dass Ihre Access-Control-Allow-Headers alle Header enthalten, die der Client senden könnte, insbesondere Authorization, Accept und benutzerdefinierte Header.
4. Mehrere Access-Control-Allow-Origin-Header zurückgeben
Einige falsch konfigurierte Proxys oder Frameworks senden mehrere Access-Control-Allow-Origin-Header (z. B. einen statischen * und einen dynamischen Ursprung).
Browser behandeln dies als ungültig und blockieren die Anfrage vollständig.
Behebung: Geben Sie immer einen einzigen gültigen Access-Control-Allow-Origin-Header zurück.
5. Methodenbeschränkungen vergessen
Wenn Sie nicht alle zulässigen Methoden in Access-Control-Allow-Methods angeben, lehnen Browser legitime Anfragen ab.
Beispielsweise könnte eine API PUT unterstützen, aber Ihre Preflight-Antwort erlaubt nur GET und POST.
Behebung: Listen Sie alle unterstützten Methoden auf oder passen Sie Ihre API-Routen dynamisch an, um Konsistenz zu gewährleisten.
6. Ignorieren zwischengespeicherter Preflight-Antworten
Moderne Browser speichern Preflight-Ergebnisse aus Leistungsgründen im Cache.
Wenn Ihr Server oder CDN jedoch Antworten ohne Variation nach Origin im Cache speichert, könnten Sie versehentlich falsche CORS-Header an einen anderen Client senden.
Behebung: Verwenden Sie den Header „Vary: Origin“, um sicherzustellen, dass Antworten pro Ursprung separat zwischengespeichert werden.
CORS-Probleme entstehen selten durch einen einzigen großen Fehler. Sie sind in der Regel das Ergebnis mehrerer kleiner Unstimmigkeiten zwischen den Erwartungen des Browsers und der Serverkonfiguration. Wenn Sie diese Muster verstehen, können Sie endlose Debugging-Zyklen aufgrund von „CORS-Fehlern“ vermeiden.
CORS ist nicht der Feind, sondern das Missverständnis davon.
Auf den ersten Blick erscheint CORS wie eine unnötige Barriere oder eher wie ein Torwächter, der Ihre Anfragen unterbricht und die Entwicklung verlangsamt.
In Wirklichkeit ist es jedoch eine der wichtigsten Sicherheitsfunktionen, die jemals für Browser entwickelt wurden.
Sobald Sie verstehen, wie es funktioniert, sehen Sie „CORS-Fehler“ nicht mehr als zufällige Fehler, sondern als Signale, dass Ihr Client und Ihr Server in Bezug auf Vertrauen, Header oder Anmeldedaten besser aufeinander abgestimmt werden müssen.
Ganz gleich, ob Sie eine Single-Page-App oder ein verteiltes API-Ökosystem entwickeln – CORS ist Ihr Verbündeter, wenn es darum geht, die Sicherheit Ihrer Nutzer zu gewährleisten und gleichzeitig eine sichere domänenübergreifende Kommunikation zu ermöglichen.
Wenn Sie also das nächste Mal diese bekannte Konsolenmeldung erhalten, greifen Sie nicht gleich zur Wildcard. Lesen Sie die Header, verfolgen Sie die Logik und lassen Sie sich bei der Fehlerbehebung von Ihrem Verständnis leiten, nicht von einem zufälligen Hack!
Sichern Sie Ihre Software jetzt.



.avif)
