Website-Pflichtencheckvon Jurono
SicherheitWebsiteTechnikCode

CORS ist keine API-Autorisierung: Was der Browser wirklich schützt

CORS entscheidet, ob Browser JavaScript eine Cross-Origin-Antwort lesen lassen. Es ersetzt weder Login noch Rollenprüfung, CSRF-Schutz oder serverseitige Zugriffskontrolle.

Von Jurono
Aktualisiert: 19. August 2026

„Die API ist geschützt. Wir haben CORS nur für unsere Frontend-Domain freigeschaltet.“

Dieser Satz klingt vernünftig und ist trotzdem gefährlich unvollständig.

CORS ist eine Browser-Sicherheitsmechanik für Cross-Origin-Freigaben von Antworten. Der WHATWG Fetch Standard beschreibt das Protokoll genau so: Response-Header teilen dem Browser mit, ob eine Antwort mit JavaScript aus einem anderen Origin geteilt werden darf. Das ist wertvoll. Aber es ist keine Benutzer-Authentifizierung, keine Rollenprüfung und keine allgemeine Firewall für Ihre API.

Der Unterschied ist praktisch wichtig: Ein API-Endpunkt kann eine fremde Website daran hindern, seine Antwort im Browser auszulesen, und trotzdem weiterhin Requests von curl, Servern, mobilen Apps oder anderen nicht browsergebundenen Clients akzeptieren. Und bestimmte browserseitige Cross-Origin-Requests können den Server erreichen, ohne dass vorher ein CORS-Preflight stattfindet.

Wer CORS als Zugriffskontrolle modelliert, schützt deshalb oft die falsche Grenze.

Mythos 1: „Wenn der Origin nicht erlaubt ist, erreicht der Request unsere API nicht“

Nicht allgemein.

Der Fetch Standard trennt zwischen dem HTTP-Request und der Frage, ob die resultierende Antwort an JavaScript eines anderen Origins freigegeben wird. Für komplexere Cross-Origin-Requests führt der Browser häufig zuerst einen Preflight per OPTIONS aus. Für Requests, die in den CORS-Safelists liegen und ungefähr dem entsprechen, was klassische HTML-Formulare auslösen können, ist ein Preflight aber nicht zwingend.

Das bedeutet: „Der Browser lässt die Antwort nicht lesen“ ist nicht dasselbe wie „der Server wurde nie angesprochen“.

Für rein lesende, öffentliche Endpunkte mag das unspektakulär sein. Für zustandsändernde Endpunkte ist es entscheidend. Ein Server muss jede fachliche Aktion selbst absichern: Ist der Nutzer authentifiziert? Darf genau dieser Nutzer genau diese Ressource sehen oder ändern? Ist die Methode für diesen Endpunkt zulässig? Ist der Request gegen Cross-Site-Aktionen ausreichend geschützt? Ist der angefragte Datensatz dem aktuellen Mandanten, Konto oder Workspace zugeordnet?

CORS kann diese Fragen nicht beantworten.

Mythos 2: „Preflight ist unsere Sicherheitsprüfung“

Ein Preflight ist eine Browser-Kompatibilitätsprüfung für den CORS-Mechanismus, keine Business-Autorisierung.

Der Browser sendet dazu einen OPTIONS-Request und kündigt unter anderem die geplante Methode und nicht safelistete Header an. Der Server kann mit Access-Control-Allow-Methods und Access-Control-Allow-Headers erklären, was für CORS akzeptiert wird.

Wichtig: Der CORS-Preflight selbst enthält laut Fetch Standard keine Credentials. Wenn Ihre Auth-Middleware jeden Request inklusive OPTIONS zwingend mit Session oder Bearer-Token prüft, kann sie legitime Preflights blockieren, bevor Ihre CORS-Konfiguration überhaupt antworten kann.

Die saubere Trennung lautet:

  1. Preflight beantwortet die Browserfrage: „Darf dieses Frontend diesen Request im CORS-Modell versuchen und die Antwort erhalten?“
  2. Der eigentliche API-Request beantwortet die Sicherheitsfrage: „Ist dieser Client für diese konkrete Aktion authentifiziert und autorisiert?“

Diese beiden Ebenen dürfen zusammenarbeiten, aber sie sollten nicht verwechselt werden.

Mythos 3: „Access-Control-Allow-Origin: * macht eine private API offen“

Bei einer wirklich privaten API ist * ein starkes Warnsignal – aber auch hier lohnt Präzision.

Der Fetch Standard erlaubt Access-Control-Allow-Origin: * vor allem für Ressourcen, die ohnehin öffentlich gelesen werden dürfen. Er formuliert eine klare Faustregel: Wenn eine Ressource von einem beliebigen Gerät per curl oder wget erreichbar sein darf, kann das öffentliche Cross-Origin-Teilen passend sein.

Für Requests mit Credentials gelten strengere Regeln. Bei credentials: include darf Access-Control-Allow-Origin nicht * sein; ein konkreter Origin und Access-Control-Allow-Credentials: true sind erforderlich.

Daraus folgt aber nicht, dass ein konkreter Origin automatisch sicher ist. Gefährlich wäre etwa, den eingehenden Origin ungeprüft in Access-Control-Allow-Origin zurückzuspiegeln und gleichzeitig Access-Control-Allow-Credentials: true zu setzen. Dann gibt es faktisch keine sinnvolle Origin-Grenze mehr, obwohl im Header nie ein Stern auftaucht.

Ein dynamischer Origin gehört deshalb gegen eine explizite, exakt definierte Allowlist geprüft. Keine Substring-Suche wie „enthält example.com“, keine unklare Suffixlogik und kein blindes Echo.

Mythos 4: „Unsere Frontend-Domain ist erlaubt, also reicht das“

Ein Origin ist nicht dasselbe wie ein Benutzer.

https://app.example.com beschreibt Schema, Host und Port-Kontext. Er sagt nicht, welche Person den Request ausführt, welche Rolle sie hat, welchem Tenant sie angehört, ob ihr Account gesperrt wurde oder ob sie Dokument 4711 sehen darf.

CORS beantwortet nur eine Browser-Sharing-Frage zwischen Origins. Fachliche Berechtigungen bleiben serverseitig. Das ist besonders wichtig bei Multi-Tenant-SaaS: Eine perfekt konfigurierte CORS-Allowlist verhindert nicht, dass Nutzer A auf Daten von Nutzer B zugreift, wenn der Server Objekt- und Tenant-Berechtigungen nicht korrekt prüft.

Origin-basierte Freigabe und objektbezogene Autorisierung sind zwei völlig verschiedene Kontrollen.

Mythos 5: „CORS schützt uns automatisch vor CSRF“

Nein.

Cross-Site Request Forgery nutzt genau die Tatsache aus, dass Browser unter bestimmten Bedingungen Requests im Kontext eines eingeloggten Nutzers auslösen können. Ob Cookies tatsächlich gesendet werden, hängt unter anderem von Cookie-Scope, SameSite, Request-Typ und Browserregeln ab. Aber CORS allein ist nicht die passende Aussage „diese zustandsändernde Aktion darf nur aus unserem UI kommen“.

Der Fetch Standard erklärt ausdrücklich, dass Preflight nur für Requests nötig ist, die über die Möglichkeiten klassischer HTML-Formulare hinausgehen. Der W3C-Entwurf zu Fetch Metadata geht noch direkter auf das Problem ein: Browser können dazu gebracht werden, Requests an Endpunkte auszulösen und dabei Umgebungs-Credentials zu verwenden; Server brauchen deshalb zusätzliche Kontextsignale und Schutzentscheidungen.

Für sensible Aktionen gehören je nach Architektur unter anderem zusammen: SameSite-Cookies bewusst konfigurieren, CSRF-Token bei cookie-basierten Sessions verwenden, wenn der Flow sie benötigt, Zustandsänderungen nicht über GET modellieren, serverseitige Origin-/Referer- oder Fetch-Metadata-Prüfungen als zusätzliche Schicht einsetzen, sensible Aktionen erneut autorisieren und unabhängig davon die fachlichen Berechtigungen prüfen.

CORS ist dabei eine Schicht, nicht die ganze Mauer.

Red Flag: CORS wird global auf „irgendwie passend“ gestellt

Viele Probleme entstehen nicht aus einem einzelnen falschen Header, sondern aus einer globalen Middleware, die für jede Route dieselbe Antwort erzeugt.

Ein öffentliches Asset, eine öffentliche API und ein eingeloggter Account-Endpunkt haben unterschiedliche Anforderungen. Trotzdem sieht man häufig: Access-Control-Allow-Origin wird global gesetzt, jede Anfrage mit Origin wird reflektiert, Access-Control-Allow-Credentials: true gilt überall, OPTIONS wird an dieselbe Auth- und Business-Logik geschickt wie normale Requests, und lokale Entwicklung, Preview und Produktion teilen eine immer länger werdende Allowlist.

Besser ist eine kleine Matrix pro API-Klasse:

EndpunktklasseCross-Origin nötig?Credentials?Erlaubte Origins
Öffentliche, nicht personalisierte Dateneventuellneinggf. *
Browser-App mit Sessionjaeventuellkonkrete App-Origins
Interne Admin-APImöglichst nein oder streng begrenztjadefinierte Admin-Origins
Server-to-Server APICORS irrelevantAPI-Authkeine Browserfreigabe nötig

CORS ist dann eine bewusste Schnittstellenentscheidung statt globaler Dekoration.

Vergessen Sie Vary: Origin nicht

Wenn der Server abhängig vom eingehenden Origin unterschiedliche Access-Control-Allow-Origin-Werte zurückgibt, muss auch Caching berücksichtigt werden.

Der Fetch Standard fordert für dynamische CORS-Antworten Vary: Origin. Sonst kann ein Cache eine Antwort speichern, die für einen anderen Origin erzeugt wurde. Das kann zu schwer reproduzierbaren Fehlern führen: Ein erlaubtes Frontend bekommt plötzlich eine gecachte Antwort ohne passende CORS-Freigabe – oder CORS-Verhalten unterscheidet sich abhängig davon, wer den Cache zuerst gefüllt hat.

Bei statischem Access-Control-Allow-Origin: * oder einem festen Origin kann die Antwort dagegen konsistent ausgeliefert werden. CDN, Reverse Proxy und API-Cache gehören deshalb mit in den Test.

Ein sauberer CORS-Audit testet mehr als den Happy Path

1. Browser mit erlaubtem Origin

Testen Sie reale Frontend-Flows ohne Login, mit Login, mit abgelaufener Session, mit Custom Headers, mit GET, POST, PUT/PATCH und DELETE sowie mit Fehlerantworten. Auch 401, 403, 404 und 500 brauchen konsistentes CORS-Verhalten, sonst sieht das Frontend nur einen generischen Netzwerkfehler.

2. Browser mit nicht erlaubtem Origin

Starten Sie dieselben Requests von einem fremden Origin. Prüfen Sie nicht nur die DevTools-Konsole, sondern auch die Serverlogs: Wurde ein Preflight gesendet? Wurde der eigentliche Request gesendet? Wurde serverseitig eine Aktion ausgelöst? War die Antwort lediglich für JavaScript nicht lesbar?

3. Nicht-Browser-Client

Rufen Sie denselben Endpunkt mit einem normalen HTTP-Client auf. Wenn die einzige Schutzlogik „Origin nicht erlaubt“ war, wird das sofort sichtbar. Eine private API muss ohne Browser genauso sauber Authentifizierung und Autorisierung erzwingen.

4. Cache- und Infrastrukturpfad

Prüfen Sie über die echte Produktionskette Browser → CDN/WAF → Reverse Proxy → API. Achten Sie auf doppelte oder widersprüchliche CORS-Header, fehlendes Vary: Origin, Proxy-Regeln für OPTIONS, unerwartete Redirects und Unterschiede zwischen Fehler- und Erfolgspfaden.

Fetch Metadata kann eine zusätzliche Kontextschicht liefern

Der W3C-Entwurf zu Fetch Metadata definiert Header wie Sec-Fetch-Site, Sec-Fetch-Mode und Sec-Fetch-Dest. Sie geben Servern Kontext darüber, wie ein Request ausgelöst wurde. Damit kann eine Anwendung zum Beispiel erkennen, dass ein Request cross-site kommt oder dass ein vermeintlicher API-Endpunkt plötzlich als Bildressource angesprochen wird.

Das kann eine starke zusätzliche Abwehrschicht sein. Aber auch hier gilt: Kontext ist keine Benutzerberechtigung. Fetch Metadata ergänzt Authentifizierung, Autorisierung und CSRF-Strategie; es ersetzt sie nicht.

Was Website-Pflichtencheck dabei prüfen würde

Bei einem CORS- und API-Grenzen-Check würden wir nicht nur nach Access-Control-Allow-Origin suchen. Geprüft werden können öffentliche, eingeloggte und administrative API-Klassen, tatsächliche erlaubte Origins, dynamisches Origin-Matching, Credential-Verhalten, Preflight-Antworten und OPTIONS-Routing, CORS-Header auf Erfolgs- und Fehlerantworten, Vary: Origin und CDN-/Proxy-Caching, Verhalten aus einem fremden Browser-Origin, Verhalten mit einem nicht browsergebundenen HTTP-Client, CSRF- und Cookie-Schutz bei zustandsändernden Aktionen, Fetch-Metadata-Signale als zusätzliche Schutzschicht und vor allem serverseitige Authentifizierung, Rollen-, Tenant- und Objektberechtigungen.

Die wichtigste Frage lautet nicht: „Ist CORS aktiviert?“

Sie lautet: „Welche Grenze soll CORS hier schützen – und welche Grenzen müssen unabhängig davon auf dem Server erzwungen werden?“

Wenn die Antwort darauf klar ist, wird CORS plötzlich viel einfacher. Es muss dann nicht mehr die Aufgabe von Login, Autorisierung, CSRF-Schutz und Netzwerkfirewall gleichzeitig spielen.

Und genau das sollte es auch nie tun.

Jurono Logo

Jurono

Technische Website-Prüfung, Website-Fixes und AI-Code-Rettung für kleine Unternehmen, Praxen, Kanzleien und Gründer:innen in Deutschland.

Holen Sie sich unsere kostenlose Sicherheitscheckliste.

Kostenlose PDF herunterladen

Erstes Signal in 30 Sekunden? Kostenlosen Website-Schnelltest starten.

Website-Hinweise per E-Mail

Alle zwei Wochen eine kurze technische Notiz. Kein Spam, kein Verkaufstalk.

Passende Angebote

Direkt weiterkommen

Basierend auf den Themen dieses Artikels – ohne lange Suche.

Manueller Website-Check

Wenn niemand genau weiß, welche Skripte, Cookie-Signale oder technischen Risiken gerade auf Ihrer Website laufen.

249

Manuelle technische Ersteinschätzung und klare Prioritäten innerhalb von 2 Werktagen.

  • Sie sehen schnell, ob Tracking, Cookies, externe Dienste oder HTTPS auffällig sind
  • Mobile-, Ladezeit- und Technik-Probleme werden verständlich eingeordnet
  • Die wichtigsten Punkte stehen in einer kurzen Prioritätenliste
Klarheit mit Manueller Website-Check

Technischer Website-Audit

Wenn die Website wichtig ist, aber unklar bleibt, welche sichtbaren Pflichtbereiche, technischen Risiken und Fixes wirklich Priorität haben.

549

Prüfung, Bewertung und konkreter Maßnahmenplan innerhalb von 3-5 Werktagen.

  • Alles aus dem manuellen Website-Check, gründlicher bewertet und dokumentiert
  • Konkrete Fundstellen zu Cookie-, Tracking- und externen Dienstsignalen
  • Sichtbare Pflichtbereiche technisch geprüft, ohne Rechtsberatung
Technischer Website-Audit anfragen

AI-Code Triage

Wenn das Projekt startet, aber niemand weiß, warum es dauernd bricht.

390

Code-Sichtung, Build-/Import-Check und Rettungsplan innerhalb von 2 Werktagen.

  • Repo-Check auf kaputte Imports, fehlende Pakete und Build-Fehler
  • Einschätzung: reparieren, neu strukturieren oder wegwerfen
  • Priorisierte Fix-Liste mit Aufwandsschätzung
Passend dazu: AI-Code Triage

Erst Klarheit, dann entscheiden.

Starten Sie mit einer technischen Prüfung. Wenn nur Kleinigkeiten auffallen, können Sie es dabei belassen, den Bericht weitergeben oder später gezielte Fixes buchen.

Technische Prüfung und Umsetzung, keine Rechtsberatung. Ich prüfe sichtbare Signale, Einbindungen und Auslieferungsprobleme; Rechtstexte und verbindliche juristische Bewertungen bleiben Aufgabe von Anwält:innen oder Datenschutzberatung.

CORS ist keine API-Autorisierung: Was der Browser wirklich schützt