🌐 CORS Optimierung¶
Problem¶
Priorität: 🟡 MITTEL
Zeitaufwand: 1 Std.
Status: ✅ BEHOBEN
Ausgangslage¶
Die CORS-Konfigurationen waren zu restriktiv und erlaubten nur GET-Requests:
- ❌ Nur GET-Methode konfiguriert
- ❌ POST/PUT/DELETE fehlten
- ❌ Cloud Functions onCall() Requests wurden blockiert
- ❌ Shop System verwendete unsicheren Wildcard-Origin ("*")
Lösung¶
Aktualisierte HTTP-Methoden¶
Alle CORS-Konfigurationen unterstützen jetzt:
| Methode | Verwendung |
|---|---|
| GET | Lesezugriffe auf Storage |
| HEAD | Metadaten-Abfragen |
| POST | Cloud Functions (onCall) |
| PUT | Datei-Uploads, Updates |
| DELETE | Datei-Löschungen |
| OPTIONS | Preflight-Requests (CORS) |
Aktualisierte Response-Headers¶
"responseHeader": [
"Content-Type", // MIME-Type der Response
"Authorization", // Auth-Token
"X-Requested-With", // AJAX-Identifikation
"Accept", // Akzeptierte Content-Types
"Origin" // Request-Origin
]
Geänderte Dateien¶
1. Root CORS-Konfigurationen¶
cors.json¶
Verwendung: Standard Development/Test Environment
Änderungen: - ✅ Alle HTTP-Methoden hinzugefügt - ✅ Erweiterte Response-Headers - ✅ Localhost-Ports für Development (3000, 5000, 8080)
Origins:
"origin": [
"https://es-dev-2-d4e1a.web.app",
"https://es-dev-2-d4e1a.firebaseapp.com",
"http://localhost:8080",
"http://localhost:5000",
"http://localhost:3000"
]
cors.dev.json¶
Status: ✅ War bereits korrekt konfiguriert (keine Änderungen nötig)
cors.prod.json¶
Verwendung: Production Environment
Änderungen:
- ✅ DELETE-Methode hinzugefügt
- ✅ Erweiterte Response-Headers (X-Requested-With, Accept, Origin)
- ✅ maxAgeSeconds auf 86400 (24h) für bessere Performance
Origins:
2. App-spezifische CORS-Konfigurationen¶
apps/shop_system/cors.json¶
Kritische Sicherheitsverbesserung:
- ❌ Vorher: "origin": ["*"] (UNSICHER!)
- ✅ Jetzt: Explizite Domain-Whitelist
- ✅ Alle HTTP-Methoden
- ✅ Vollständige Response-Headers
apps/erp_system/cors.json¶
Änderungen: - ✅ Alle HTTP-Methoden hinzugefügt - ✅ Erweiterte Response-Headers - ✅ Localhost-Ports für Development
Deployment¶
Firebase Storage CORS¶
Die CORS-Konfigurationen für Firebase Storage müssen mit gsutil deployed werden:
# Development Environment
./deploy_storage_cors.sh dev gs://your-dev-bucket.appspot.com
# Production Environment
./deploy_storage_cors.sh prod gs://your-prod-bucket.appspot.com
Der Script deploy_storage_cors.sh: - ✅ Validiert Konfigurationsdatei - ✅ Zeigt Vorschau der Änderungen - ✅ Fragt nach Bestätigung - ✅ Deployed zu Firebase Storage - ✅ Verifiziert Deployment
Cloud Functions CORS¶
Wichtig: Cloud Functions v2 mit onCall() haben CORS bereits eingebaut!
Die folgenden Functions nutzen automatisch die korrekten CORS-Einstellungen:
- createJob
- updateJob
- deleteJob
- storeConnectorCredentials
- updateConnectorCredentials
- deleteConnector
- testConnectorConnection
- getConnectorCredentials
- toggleConnectorActive
Firebase Functions v2 erlaubt automatisch: - POST-Requests von allen origins in der Firebase Hosting Config - OPTIONS-Requests für Preflight - Korrekte CORS-Headers in Responses
Kein zusätzliches Deployment erforderlich!
Sicherheits-Improvements¶
Vorher vs. Nachher¶
| Aspekt | Vorher ❌ | Nachher ✅ |
|---|---|---|
| HTTP-Methoden | Nur GET | GET, HEAD, POST, PUT, DELETE, OPTIONS |
| Shop Origin | Wildcard * |
Explizite Whitelist |
| Response-Headers | Minimal | Vollständig |
| Cloud Functions | Blockiert | Voll funktional |
| OWASP-Konformität | Teilweise | Vollständig |
Sicherheits-Checkliste¶
- ✅ Keine Wildcard-Origins in Production
- ✅ Explizite Domain-Whitelist
- ✅ Minimale erforderliche HTTP-Methoden
- ✅ Explizite Response-Headers
- ✅ Cache-Steuerung (maxAgeSeconds)
- ✅ Development/Production Trennung
Testing¶
1. Cloud Functions Test¶
// Frontend Code
const functions = getFunctions();
const createJob = httpsCallable(functions, 'createJob');
try {
const result = await createJob({
name: 'Test Job',
type: 'import',
customerId: 'test123',
schedule: { type: 'cron', expression: '0 0 * * *' }
});
console.log('✅ Job created:', result.data);
} catch (error) {
console.error('❌ CORS Error:', error);
}
2. Storage Upload Test¶
// Frontend Code
const storage = getStorage();
const fileRef = ref(storage, 'test/file.txt');
try {
await uploadBytes(fileRef, blob);
console.log('✅ Upload successful');
} catch (error) {
console.error('❌ CORS Error:', error);
}
3. Browser Console Test¶
Öffne die Browser Developer Tools und prüfe:
Erfolgreiche CORS-Response:
Access-Control-Allow-Origin: https://es-dev-2-d4e1a.web.app
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With
CORS-Fehler (sollte NICHT mehr auftreten):
Häufige Probleme¶
Problem 1: "CORS policy: No 'Access-Control-Allow-Origin' header"¶
Ursache: Storage CORS nicht deployed
Lösung:
Problem 2: "Method not allowed"¶
Ursache: HTTP-Methode nicht in CORS konfiguriert
Lösung: Prüfe, ob die Methode in cors.json enthalten ist:
Problem 3: Cloud Function gibt 403¶
Ursache: Nicht CORS, sondern Autorisierung!
Lösung: Prüfe User-Rolle in SECURITY_IMPLEMENTATION.md: - Admin (userRole ≥ 1): Create/Update - SuperAdmin (userRole ≥ 2): Delete/Credentials
Problem 4: Preflight Request schlägt fehl¶
Ursache: OPTIONS-Methode fehlt
Lösung: OPTIONS ist jetzt in allen Configs enthalten ✅
Integration mit Security Implementation¶
Diese CORS-Optimierung ergänzt die Security Implementation:
| Security Layer | Funktion |
|---|---|
| CORS | Kontrolliert, welche Origins Requests senden dürfen |
| Input Validation | Validiert Request-Daten |
| Authorization | Prüft User-Berechtigungen |
| Rate Limiting | Verhindert Denial-of-Service |
Zusammenspiel: 1. Browser sendet Preflight OPTIONS-Request → CORS prüft Origin ✅ 2. CORS erlaubt Request → Cloud Function empfängt POST ✅ 3. Input Validation prüft Daten → Daten validiert ✅ 4. Authorization prüft userRole → User autorisiert ✅ 5. Rate Limiting prüft Anfragen → Limit OK ✅ 6. Function führt Action aus → Erfolg! ✅
Monitoring¶
CORS-Fehler in Logs finden¶
# Firebase Functions Logs
gcloud functions logs read --region=europe-west1 \
--filter="textPayload:CORS OR textPayload:Access-Control"
# Browser Console
# Network Tab → Filter by "CORS error" → Check Response Headers
Metriken¶
Überwache CORS-bezogene Fehler:
// In Cloud Functions
console.log('CORS_ERROR', {
origin: request.headers.origin,
method: request.method,
function: 'createJob'
});
Nächste Schritte (Optional)¶
1. Firebase App Check Integration¶
// Cloud Functions mit App Check
exports.createJob = onCall({
enforceAppCheck: true, // ✅ Aktivieren für zusätzliche Sicherheit
cors: true, // Bereits standardmäßig aktiv
}, async (request) => {
// ...
});
2. Content Security Policy (CSP)¶
Füge zu Flutter Web index.html hinzu:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
connect-src 'self' https://*.googleapis.com https://*.cloudfunctions.net;">
3. Production Domain aktualisieren¶
Wichtig: Aktualisiere in cors.prod.json:
Rollback¶
Falls Probleme auftreten:
# 1. Alte Konfiguration wiederherstellen
git checkout HEAD~1 cors.json cors.prod.json
# 2. Storage CORS neu deployen
./deploy_storage_cors.sh dev gs://your-bucket.appspot.com
# 3. Cloud Functions neu deployen (falls geändert)
cd functions && firebase deploy --only functions
Checkliste für Production Deployment¶
Vor dem Production-Deployment prüfen:
- [ ] Production Domain in
cors.prod.jsonaktualisiert - [ ] Keine Wildcard-Origins (
*) - [ ] Nur benötigte HTTP-Methoden aktiviert
- [ ] Nur benötigte Response-Headers
- [ ] maxAgeSeconds angemessen (dev: 3600s, prod: 86400s)
- [ ] Storage CORS mit
deploy_storage_cors.shdeployed - [ ] CORS-Funktionalität getestet
- [ ] Keine CORS-Fehler in Browser Console
- [ ] Cloud Functions erreichbar
- [ ] Storage Upload/Download funktioniert
Status: ✅ Vollständig implementiert
Letzte Aktualisierung: 24. Februar 2026
OWASP Finding behoben: Security Misconfiguration (A05)
Breaking Changes: Keine - abwärtskompatibel