167 lines
4.8 KiB
Markdown
167 lines
4.8 KiB
Markdown
|
|
# STEP 4.4 – KLARTEXT-CREDENTIALS ENTFERNT (LÜCKE #28)
|
|||
|
|
# Status: ABGESCHLOSSEN
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Fundstellen
|
|||
|
|
|
|||
|
|
| Datei | Problem |
|
|||
|
|
|-------|---------|
|
|||
|
|
| `aza_email_config.json` | Klartext-Passwort im `password`-Feld: `"password": "Asdfasdf22@@As96k324"` |
|
|||
|
|
|
|||
|
|
Keine weiteren Klartext-Credentials in JSON/YAML/INI-Dateien gefunden.
|
|||
|
|
|
|||
|
|
**Hinweis:** Das hier entfernte Passwort war ein echtes Produktivpasswort.
|
|||
|
|
Es sollte umgehend beim Mail-Provider geändert werden.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Neue ENV-Variablen
|
|||
|
|
|
|||
|
|
| Variable | Beschreibung |
|
|||
|
|
|----------|-------------|
|
|||
|
|
| `AZA_EMAIL_PASSWORD_0` | Passwort für das erste E-Mail-Konto |
|
|||
|
|
| `AZA_EMAIL_PASSWORD_1` | Passwort für das zweite E-Mail-Konto (falls vorhanden) |
|
|||
|
|
| `AZA_EMAIL_PASSWORD_N` | Passwort für das N-te Konto (0-basiert) |
|
|||
|
|
|
|||
|
|
### Setzen unter Windows:
|
|||
|
|
```cmd
|
|||
|
|
set AZA_EMAIL_PASSWORD_0=MeinSicheresPasswort
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Setzen unter Linux/Mac:
|
|||
|
|
```bash
|
|||
|
|
export AZA_EMAIL_PASSWORD_0="MeinSicheresPasswort"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Dauerhaft (Windows PowerShell):
|
|||
|
|
```powershell
|
|||
|
|
[Environment]::SetEnvironmentVariable("AZA_EMAIL_PASSWORD_0", "MeinPasswort", "User")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Geänderte Dateien
|
|||
|
|
|
|||
|
|
| Datei | Änderung |
|
|||
|
|
|-------|----------|
|
|||
|
|
| `aza_email.py` | Neue Funktionen: `_get_account_password()`, `_strip_passwords()`, `_check_plaintext_migration()` |
|
|||
|
|
| `aza_email.py` | `load_email_config()`: Lädt Passwörter aus ENV, ignoriert Klartext in JSON, gibt Warnung |
|
|||
|
|
| `aza_email.py` | `save_email_config()`: Strippt `password` und `_password` vor dem Schreiben |
|
|||
|
|
| `aza_email.py` | Alle IMAP/SMTP-Stellen: `acc.get("password")` → `acc.get("_password")` |
|
|||
|
|
| `aza_email.py` | Account-Dialog: Passwort wird als `_password` (RAM-only) gespeichert |
|
|||
|
|
| `aza_email_config.json` | Klartext-Passwort entfernt |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Architektur
|
|||
|
|
|
|||
|
|
### Passwort-Fluss (NEU):
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
ENV (AZA_EMAIL_PASSWORD_0)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
load_email_config() ──► acc["_password"] (nur RAM)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
IMAP/SMTP Login ──► acc.get("_password", "")
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
save_email_config() ──► _strip_passwords() ──► JSON OHNE Passwort
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Passwort-Fluss (GUI-Eingabe):
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Account-Dialog (Passwort-Feld)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
save_account() ──► acc["_password"] = pw_input (nur RAM)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
_save_config() ──► save_email_config() ──► _strip_passwords() ──► JSON OHNE Passwort
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Das `_password`-Feld existiert NUR im RAM. Es wird NIE in JSON geschrieben.
|
|||
|
|
Das `password`-Feld wird beim Laden aus JSON ignoriert und beim Speichern entfernt.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Migrationsverhalten
|
|||
|
|
|
|||
|
|
Wenn `aza_email_config.json` noch ein `password`-Feld enthält:
|
|||
|
|
|
|||
|
|
1. **Warnung auf stderr:**
|
|||
|
|
```
|
|||
|
|
SICHERHEITSWARNUNG: Klartext-Passwoerter in aza_email_config.json gefunden!
|
|||
|
|
Betroffene Konten: andre.surovy@haut-winterthur.ch
|
|||
|
|
Bitte entfernen und stattdessen ENV-Variablen setzen:
|
|||
|
|
AZA_EMAIL_PASSWORD_0
|
|||
|
|
Die Passwoerter in der Datei werden IGNORIERT.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **Klartext-Passwort wird NICHT übernommen** (kein Auto-Migrate)
|
|||
|
|
3. **Benutzer muss ENV-Variable setzen**, damit E-Mail funktioniert
|
|||
|
|
4. **Beim nächsten Speichern** wird das `password`-Feld automatisch entfernt
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Fail-Start Verhalten
|
|||
|
|
|
|||
|
|
| Szenario | Ergebnis |
|
|||
|
|
|----------|----------|
|
|||
|
|
| `AZA_EMAIL_PASSWORD_0` gesetzt | E-Mail funktioniert |
|
|||
|
|
| `AZA_EMAIL_PASSWORD_0` nicht gesetzt | E-Mail-Abruf zeigt: "Konto-Daten unvollständig" |
|
|||
|
|
| Klartext-PW in JSON | Warnung + wird ignoriert |
|
|||
|
|
| GUI-Passworteingabe | Funktioniert für Sitzung (nicht persistent) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Testergebnis
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
12/12 PASS, 0/12 FAIL
|
|||
|
|
GESAMTBEWERTUNG: PASS
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
| Test | Ergebnis |
|
|||
|
|
|------|----------|
|
|||
|
|
| Kein Passwort in JSON | PASS |
|
|||
|
|
| Warnung auf stderr bei Klartext | PASS |
|
|||
|
|
| Passwort NICHT in geladenen Daten | PASS |
|
|||
|
|
| ENV-PW in _password Feld | PASS |
|
|||
|
|
| Kein password Feld nach Laden | PASS |
|
|||
|
|
| Kein password in gespeicherter Datei | PASS |
|
|||
|
|
| Kein _password in gespeicherter Datei | PASS |
|
|||
|
|
| password entfernt (Konto 1) | PASS |
|
|||
|
|
| password entfernt (Konto 2) | PASS |
|
|||
|
|
| _password entfernt (nie auf Disk) | PASS |
|
|||
|
|
| Andere Felder erhalten | PASS |
|
|||
|
|
| Kein print mit password-Wert | PASS |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Rest-Risiken
|
|||
|
|
|
|||
|
|
1. **Passwort im RAM:** Während der Sitzung liegt das Passwort im RAM
|
|||
|
|
(Python-String). Für eine Desktop-App akzeptabel.
|
|||
|
|
|
|||
|
|
2. **ENV-Variable sichtbar:** `AZA_EMAIL_PASSWORD_0` kann in Prozesslisten
|
|||
|
|
sichtbar sein. Empfehlung für Zukunft: OS-Keychain-Integration
|
|||
|
|
(Windows Credential Manager / macOS Keychain).
|
|||
|
|
|
|||
|
|
3. **Altes Passwort exponiert:** Das Passwort `Asdfasdf22@@As96k324` war
|
|||
|
|
in der JSON-Datei gespeichert. Es sollte beim Provider geändert werden.
|
|||
|
|
|
|||
|
|
4. **Backup-Dateien:** Die Kopie-Dateien (`aza_email - Kopie.py`, etc.)
|
|||
|
|
enthalten noch den alten Code. Diese sind Backups und nicht aktiv.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Repo-Hygiene
|
|||
|
|
|
|||
|
|
- Kein Git-Repository vorhanden → kein `.gitignore`-Eintrag nötig
|
|||
|
|
- Kein History-Rewrite nötig
|
|||
|
|
- `aza_email_config.json` wurde direkt bereinigt (Passwort entfernt)
|