4.8 KiB
4.8 KiB
STEP 4.3 – HARDCODED SECRET KEY ENTFERNT (LÜCKE #19)
Status: ABGESCHLOSSEN
Fundstellen
| Datei | Zeile | Problem |
|---|---|---|
workforce_planner/config.py |
18 | SECRET_KEY = os.getenv("WP_SECRET_KEY", "dev-secret-change-in-production") – Hardcoded Fallback-Secret |
workforce_planner/api/auth.py |
35, 47 | Konsument: JWT encode/decode mit SECRET_KEY |
Keine weiteren hardcoded Secrets gefunden:
basis14.py: OPENAI_API_KEY kommt aus ENV, kein Fallbackbasis14.py: MEDWORK_API_TOKEN kommt aus ENV oder Datei, kein hardcoded Wertaza_email_config.json: Passwörter im Klartext (separates GAP, nicht in diesem Schritt)
Neue ENV-Variablen
| Variable | Pflicht | Beschreibung |
|---|---|---|
AZA_SECRET_KEY |
Ja (ausser DEV) | JWT-Signing-Key, min. 32 Zeichen |
AZA_ENV |
Nein | dev = erlaubt auto-generierten Key |
Alte Variable WP_SECRET_KEY wird nicht mehr verwendet.
Implementierung
workforce_planner/config.py (komplett neu)
ALT:
SECRET_KEY = os.getenv("WP_SECRET_KEY", "dev-secret-change-in-production")
NEU:
def _load_secret_key() -> str:
key = os.getenv("AZA_SECRET_KEY", "").strip()
env_mode = os.getenv("AZA_ENV", "").strip().lower()
# Kein Key: DEV auto-gen oder Fail-Start
if not key:
if env_mode == "dev":
return secrets.token_hex(64) # temporär, nur diese Session
sys.exit(1) # Fehlermeldung + Exit
# Zu kurz (< 32 Zeichen): Fail-Start
if len(key) < 32:
sys.exit(1)
# Triviales Muster: Fail-Start
for pattern in ("dev", "test", "password", "secret", ...):
if key.startswith(pattern) und nicht-alphanumerisches Folgezeichen:
sys.exit(1)
return key
SECRET_KEY = _load_secret_key()
workforce_planner/api/auth.py
Keine Änderung nötig – importiert weiterhin SECRET_KEY aus config.py.
Die Variable hat denselben Namen, der Wert kommt jetzt validiert aus ENV.
Fail-Start Verhalten
| Szenario | Ergebnis |
|---|---|
Kein AZA_SECRET_KEY, kein AZA_ENV=dev |
Exit 1 + Fehlermeldung |
AZA_ENV=dev, kein Key |
OK (auto-gen, Warnung auf stderr) |
| Key < 32 Zeichen | Exit 1 + "zu kurz" |
| Key mit trivialem Muster ("dev-...", "test-...", "password...") | Exit 1 + "triviales Muster" |
| Gültiger Key >= 32 Zeichen | OK |
Nur WP_SECRET_KEY gesetzt (alt) |
Exit 1 (wird ignoriert) |
Testkommandos + erwartete Outputs
1. Fail-Start (kein Key)
python -c "from workforce_planner.config import SECRET_KEY"
# → Exit 1: FEHLER: AZA_SECRET_KEY ist nicht gesetzt.
2. DEV-Modus (auto-gen)
AZA_ENV=dev python -c "from workforce_planner.config import SECRET_KEY; print(len(SECRET_KEY))"
# → 128 (hex-encoded 64 Bytes) + Warnung auf stderr
3. Zu kurzer Key
AZA_SECRET_KEY=short123 python -c "from workforce_planner.config import SECRET_KEY"
# → Exit 1: FEHLER: AZA_SECRET_KEY ist zu kurz (8 Zeichen, Minimum: 32)
4. Triviales Muster
AZA_SECRET_KEY="test-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" python -c "from workforce_planner.config import SECRET_KEY"
# → Exit 1: FEHLER: AZA_SECRET_KEY enthält triviales Muster ('test')
5. Gültiger Key
AZA_SECRET_KEY=$(python -c "import secrets; print(secrets.token_hex(64))") python -c "from workforce_planner.config import SECRET_KEY; print('OK:', len(SECRET_KEY), 'chars')"
# → OK: 128 chars
Testergebnis (automatisiert)
12/12 PASS, 0/12 FAIL
GESAMTBEWERTUNG: PASS
| Test | Ergebnis |
|---|---|
| Fail-Start ohne Key | PASS |
| Fehlermeldung enthält 'AZA_SECRET_KEY' | PASS |
| DEV auto-gen Key | PASS |
| Key geladen (128 chars) | PASS |
| Warnung ausgegeben | PASS |
| Fail-Start kurzer Key | PASS |
| Fehlermeldung 'zu kurz' | PASS |
| Fail-Start alter Fallback | PASS |
| Fail-Start triviales Pattern (lang) | PASS |
| Start mit gültigem Key | PASS |
| Key geladen (64 chars) | PASS |
| WP_SECRET_KEY allein -> Fail-Start | PASS |
Session/Token-Invalidierung
Impact: Bestehende JWT-Tokens (HS256), die mit dem alten Fallback-Key
"dev-secret-change-in-production" signiert wurden, werden nach dem
Setzen eines neuen AZA_SECRET_KEY ungültig.
- Betroffene Nutzer müssen sich einmalig neu anmelden.
- Dies betrifft nur den
workforce_planner(Arbeitsplan-Modul). basis14.pyverwendet keine JWT-Tokens (nur lokales Passwort-Hashing).- Keine komplexe Rotation implementiert (nicht im Scope dieses Schrittes).
- Bei Produktivbetrieb: Key einmalig setzen und dauerhaft beibehalten.
Geänderte Dateien
| Datei | Änderung |
|---|---|
workforce_planner/config.py |
Hardcoded Fallback entfernt, _load_secret_key() mit Validierung + Fail-Start implementiert |