Skip to content
IsSafeSite
2 Min. LesezeitIsSafeSite Team

CORS erklärt: Sichere Cross-Origin-Konfiguration für moderne Sites

CORS wird so oft missverstanden wie falsch konfiguriert. Hier ist, was die Header wirklich tun, die Wildcard-plus-Credentials-Falle und wie man eine API korrekt absichert.

CORSAPIsHärtung

Cross-Origin Resource Sharing (CORS) ist oft der erste Kontakt eines Teams mit Browser-Sicherheit — meist, weil etwas kaputtging und das schnellste Suchergebnis riet, „einfach alle Origins zu erlauben“. Diese Lösung funktioniert und wird still zur Schwachstelle. Hier ist, was CORS wirklich tut, und wie man es konfiguriert, ohne die API für jede Site im Internet zu öffnen.

Was CORS tatsächlich steuert

CORS ist keine serverseitige Zugriffskontrolle. Es ist ein Browser-Mechanismus, der entscheidet, ob JavaScript auf Origin A eine Antwort von Origin B *lesen* darf. Es tut nichts, um eine direkte Anfrage von curl, einem Server oder einem Skript zu stoppen, das den Browser ignoriert. Behandeln Sie es als Leitplanke für Browser-Clients und belassen Sie die echte Autorisierung ohnehin auf dem Server.

Die Wildcard-plus-Credentials-Falle

Die mit Abstand gefährlichste CORS-Konfiguration spiegelt die Anfrage-Origin zurück und erlaubt zugleich Credentials:

Access-Control-Allow-Origin: https://evil.example
Access-Control-Allow-Credentials: true

Wenn Ihr Server jeden empfangenen Origin zurückgibt und Allow-Credentials: true setzt, kann jede Site als Ihr eingeloggter Nutzer authentifizierte Anfragen stellen und die Antwort lesen. Deshalb verbietet der Browser das wörtliche * zusammen mit Credentials — doch das Spiegeln der Origin umgeht diese Sicherheit und reißt das Loch wieder auf.

Eine korrekte, restriktive Konfiguration

Gleichen Sie die eingehende Origin mit einer expliziten Erlaubnisliste ab und geben Sie sie erst dann zurück:

const allowed = new Set([
  'https://app.example.com',
  'https://admin.example.com',
]);

const origin = req.headers.get('origin');
if (origin && allowed.has(origin)) {
  res.setHeader('Access-Control-Allow-Origin', origin);
  res.setHeader('Vary', 'Origin');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
}

Der Vary: Origin-Header wird leicht vergessen und ist wichtig: Ohne ihn kann ein Cache den Erlaubnis-Header der einen Origin an eine andere ausliefern.

Begrenzen Sie auch Methoden und Header

Access-Control-Allow-Origin ist nur die halbe Policy. Halten Sie den Rest eng:

  • Erlauben Sie nur die Methoden, die der Endpunkt nutzt, z. B. Access-Control-Allow-Methods: GET, POST.
  • Erlauben Sie nur die erwarteten Request-Header, keine pauschale Liste.
  • Setzen Sie ein sinnvolles Access-Control-Max-Age, damit Preflight-Anfragen zwischengespeichert werden.
  • Kombinieren Sie Allow-Origin: * niemals mit Allow-Credentials: true.

Wann eine Wildcard tatsächlich in Ordnung ist

Eine wirklich öffentliche, nicht authentifizierte, schreibgeschützte API — ein Wechselkurs-Feed, ein öffentlicher Status-Endpunkt — kann Access-Control-Allow-Origin: * sicher nutzen, gerade weil es keine Credentials und nichts Privates zum Leaken gibt. Die Gefahr ist immer nur die *-artige Offenheit in Kombination mit Authentifizierung.

Testen Sie aus einem echten Cross-Origin-Kontext

CORS verhält sich bei einfachen und bei preflighteten Anfragen unterschiedlich, testen Sie also beide aus einem Browser auf einer anderen Origin, nicht nur mit curl (das CORS völlig ignoriert). Ein Scan prüft Ihre CORS-Antwort-Header automatisch zusammen mit Ihren übrigen Sicherheitsprüfungen; wie CORS-Befunde in eine priorisierte Fix-Liste passen, lesen Sie in So lesen Sie einen Website-Sicherheitsbericht.

Machen Sie aus diesen Prüfungen einen Scan-Bericht für Ihre eigene Site.

Starten Sie einen kostenlosen Scan und erhalten Sie in etwa 30 Sekunden priorisierte, umsetzbare Befunde.

Meine Site scannen

Weiterlesen