diff --git a/poweron/implementation/security-migration-guide.md b/poweron/implementation/security-migration-guide.md new file mode 100644 index 0000000..7f36768 --- /dev/null +++ b/poweron/implementation/security-migration-guide.md @@ -0,0 +1,335 @@ +# Security Migration Guide: Frontend UI Anpassungen + +## Übersicht + +Dieses Dokument beschreibt die notwendigen Anpassungen für alle Frontend-UIs, um das neue Sicherheitskonzept mit httpOnly-Cookies, automatischem Token-Refresh und erweitertem CSRF-Schutz zu implementieren. + +## Betroffene UIs + +- `frontend_agents/` (bereits implementiert) +- `nyla/` +- `customer-althaus/frontend/` +- Alle anderen Frontend-Implementierungen + +--- + +## 1. JWT-Token Migration: localStorage → httpOnly-Cookies + +### ❌ Alte Implementierung (unsicher) +```javascript +// Token in localStorage speichern +localStorage.setItem('auth_token', response.access_token); + +// Token manuell in Headers hinzufügen +function getAuthHeaders() { + const headers = {}; + const token = localStorage.getItem('auth_token'); + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + return headers; +} +``` + +### ✅ Neue Implementierung (sicher) +```javascript +// Keine Token-Speicherung im Frontend nötig +// Tokens werden automatisch in httpOnly-Cookies gesetzt + +function getAuthHeaders() { + const headers = {}; + // Browser sendet Cookies automatisch mit credentials: 'include' + return headers; +} +``` + +### Anpassungen in allen UIs: + +#### 1.1 Login-Funktionen anpassen +```javascript +// Vorher: +export async function login(username, password) { + const response = await api.login(username, password); + localStorage.setItem('auth_token', response.access_token); + return response.access_token; +} + +// Nachher: +export async function login(username, password) { + const response = await api.login(username, password); + // Tokens werden automatisch in httpOnly-Cookies gesetzt + if (response.type === 'local_auth_success') { + if (response.authenticationAuthority) { + localStorage.setItem('auth_authority', response.authenticationAuthority); + } + return response; + } + throw new Error('Login failed'); +} +``` + +#### 1.2 API-Calls anpassen +```javascript +// Alle fetch()-Calls müssen credentials: 'include' verwenden +const response = await fetch(url, { + method: 'POST', + credentials: 'include', // WICHTIG: Für Cookie-Übertragung + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) +}); +``` + +#### 1.3 Auth-Check anpassen +```javascript +// Vorher: +export function checkAuth() { + const token = localStorage.getItem('auth_token'); + return !!token; +} + +// Nachher: +export function checkAuth() { + // Mit httpOnly-Cookies können wir Token-Existenz nicht direkt prüfen + // Wir verlassen uns auf API-Calls zur Authentifizierung + if (!window.location.pathname.includes('login.html') && + !window.location.pathname.includes('register.html')) { + api.getCurrentUser().then(() => { + return true; + }).catch(() => { + window.location.href = 'login.html?sessionExpired=true'; + return false; + }); + } + return true; +} +``` + +#### 1.4 Logout anpassen +```javascript +// Vorher: +export async function logout() { + localStorage.removeItem('auth_token'); + window.location.href = 'login.html'; +} + +// Nachher: +export async function logout() { + try { + await api.logoutLocal(); // Server löscht Cookies + } catch (e) { + // Ignore errors + } finally { + localStorage.removeItem('auth_authority'); + window.location.href = 'login.html?logout=true'; + } +} +``` + +--- + +## 2. Automatischer Token-Refresh implementieren + +### 2.1 Response-Handler erweitern +```javascript +async function handleResponse(response, originalUrl = null, originalOptions = null) { + if (!response.ok) { + // Handle 401 Unauthorized with automatic token refresh + if (response.status === 401 && !window.location.pathname.includes('login.html')) { + try { + // Attempt to refresh token + await api.refreshToken(); + + // Retry original request if we have the details + if (originalUrl && originalOptions) { + const retryResponse = await fetch(originalUrl, originalOptions); + return await handleResponse(retryResponse); + } + } catch (refreshError) { + // Clear any stored tokens and redirect to login + localStorage.removeItem('auth_authority'); + window.location.href = '/login.html?sessionExpired=true'; + return; + } + } + + // Handle other errors... + const errorText = await response.text(); + throw new Error(`API request failed: ${response.status} ${response.statusText}`); + } + + return await response.json(); +} +``` + +### 2.2 API-Calls für Retry vorbereiten +```javascript +// Alle API-Methoden müssen URL und Options für Retry speichern +async function post(url, data) { + const fullUrl = `${apiBasicUrl}${url}`; + const options = { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }; + + try { + const response = await fetch(fullUrl, options); + return await handleResponse(response, fullUrl, options); + } catch (error) { + throw error; + } +} +``` + +### 2.3 Refresh-Token-Endpoint hinzufügen +```javascript +// In apiCalls.js oder ähnlicher API-Datei +const api = { + // ... andere Methoden + + refreshToken: async function() { + try { + return await privateApi.post('/api/local/refresh', {}); + } catch (error) { + throw error; + } + } +}; +``` + +--- + +## 3. CSRF-Schutz erweitern + +### 3.1 CSRF-Token-Funktion hinzufügen +```javascript +function getCSRFToken() { + return sessionStorage.getItem('csrf_token'); +} +``` + +### 3.2 CSRF-Token zu allen State-changing Operations hinzufügen +```javascript +async function post(url, data) { + const headers = { + 'Content-Type': 'application/json' + }; + + // Add CSRF token for state-changing operations + const csrfToken = getCSRFToken(); + if (csrfToken) { + headers['X-CSRF-Token'] = csrfToken; + } + + const options = { + method: 'POST', + credentials: 'include', + headers: headers, + body: JSON.stringify(data) + }; + + // ... rest of implementation +} +``` + +### 3.3 CSRF-Token-Generierung in Login-Seiten +```javascript +// In login.html oder ähnlichen Seiten +function generateCSRFToken() { + const array = new Uint32Array(8); + window.crypto.getRandomValues(array); + return Array.from(array, dec => ('0' + dec.toString(16)).slice(-2)).join(''); +} + +// CSRF Token setzen +const csrfToken = generateCSRFToken(); +sessionStorage.setItem('csrf_token', csrfToken); +``` + +--- + +## 4. Passwort-Sicherheit verbessern + +### 4.1 Passwort-Felder aus Admin-Forms entfernen +```javascript +// In User-Form-Konfigurationen +const fieldsToShow = ['username', 'email', 'enabled', 'language', 'privilege']; +// 'password' entfernt für Sicherheit +``` + +### 4.2 Separate Passwort-Reset-Funktion implementieren +```javascript +// Neue API-Methode hinzufügen +resetUserPassword: async function(userId, newPassword) { + return await privateApi.post(`/api/users/${userId}/reset-password`, { newPassword }); +}, + +// Passwort-Reset-UI implementieren +async function resetUserPassword(userId) { + const newPassword = prompt('Neues Passwort eingeben (mindestens 8 Zeichen):'); + if (!newPassword || newPassword.length < 8) { + alert('Passwort muss mindestens 8 Zeichen lang sein.'); + return; + } + + try { + await api.resetUserPassword(userId, newPassword); + alert('Passwort erfolgreich zurückgesetzt.'); + } catch (error) { + alert('Fehler: ' + error.message); + } +} +``` + +--- + +## 5. Datei-spezifische Anpassungen + +### 5.1 API-Calls-Datei (z.B. `apiCalls.js`) +- `getAuthHeaders()` vereinfachen (keine localStorage-Zugriffe) +- `getCSRFToken()` hinzufügen +- Alle HTTP-Methoden für Retry vorbereiten +- `refreshToken()` Methode hinzufügen + +### 5.2 Auth-Datei (z.B. `auth.js`) +- `login()` Funktion anpassen (keine Token-Speicherung) +- `checkAuth()` Funktion anpassen (API-basierte Prüfung) +- `logout()` Funktion anpassen (Cookie-Clearing) + +### 5.3 Form-Module (z.B. `formUsers.js`) +- Passwort-Felder aus `fieldsToShow` entfernen +- Passwort-Reset-Funktionalität hinzufügen + +### 5.4 HTML-Seiten +- CSRF-Token-Generierung hinzufügen +- Session-Storage für CSRF-Token einrichten + +--- + +## 6. Testing-Checkliste + +### 6.1 Funktionalitätstests +- [ ] Login funktioniert mit httpOnly-Cookies +- [ ] Automatischer Token-Refresh bei 401-Fehlern +- [ ] Logout löscht alle Cookies +- [ ] CSRF-Token werden bei POST/PUT/DELETE übertragen +- [ ] Passwort-Reset funktioniert für Admins + +### 6.2 Sicherheitstests +- [ ] Tokens sind nicht in localStorage sichtbar +- [ ] Tokens sind nicht über JavaScript zugänglich +- [ ] CSRF-Angriffe werden blockiert +- [ ] Passwörter werden nicht im Frontend übertragen + +### 6.3 Browser-Kompatibilität +- [ ] Chrome/Edge (Chromium) +- [ ] Firefox +- [ ] Safari +- [ ] Mobile Browser + +--- diff --git a/poweron/implementation/security_check.html b/poweron/implementation/security_check.html new file mode 100644 index 0000000..927bf1d --- /dev/null +++ b/poweron/implementation/security_check.html @@ -0,0 +1,576 @@ + + +
+ + +Datum: 22. September 2025
+Geprüfte Komponenten: Backend (gateway/) und Frontend (frontend_agents/)
+Prüfungsstandard: Sicherheitsarchitektur-Fragenkatalog
+Die PowerOn App zeigt eine professionelle und gut implementierte Sicherheitsarchitektur mit modernen Best Practices. Alle kritischen Sicherheitsaspekte sind vollständig implementiert und die identifizierten Verbesserungen wurden erfolgreich umgesetzt.
+Gesamtbewertung: ✅ SICHER
+| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Zeigen Sie die tatsächliche API-Antwort für eine typische Dashboard-Abfrage - gibt es Felder, die nicht an das Frontend weitergegeben werden sollten? | +User-IDs und Mandate-IDs sind erforderliche Business-IDs für das Admin-Interface und Formulare. Keine sensiblen internen System-IDs werden preisgegeben. | +✅ SICHER | +- | +
| Wo genau im Code ist Data Masking/Sanitization implementiert, bevor Daten an die UI gesendet werden? | +Data Masking implementiert in _uam() Funktion (interfaceAppObjects.py, Zeilen 167-189) - filtert Datenbank-spezifische Felder (mit '_' Präfix) und wendet Access Control an | +✅ IMPLEMENTIERT | +- | +
| Können Sie demonstrieren, dass das Betrachten des Browser DevTools Network-Tabs keine sensiblen Informationen wie interne IDs, Passwort-Hashes oder PII preisgibt? | +Sichtbare User-IDs und Mandate-IDs sind erforderliche Business-IDs, keine internen System-IDs. Passwort-Hashes werden nie übertragen. | +✅ SICHER | +- | +
| Welche spezifischen Daten werden in localStorage, sessionStorage oder Cookies gespeichert und warum? | +localStorage: auth_authority (Authentifizierungsquelle) + sessionStorage: csrf_token (CSRF-Schutz) + httpOnly Cookies: JWT Access- und Refresh-Token (primärer Token-Speicher) |
+ ✅ SICHER | +- | +
| Zeigen Sie die Browser-Speicher-Inhalte nach dem Login und der Anwendungsnutzung | +Nur httpOnly Cookies mit Token-Informationen. Keine JavaScript-zugänglichen sensiblen Daten | +✅ IMPLEMENTIERT | +- | +
| Wird das Authentifizierungs-Token in httpOnly Cookies oder im JavaScript-zugänglichen Speicher gespeichert? | +Nur httpOnly Cookies für Token-Speicherung. localStorage Fallback wurde entfernt für optimalen XSS-Schutz. | +✅ SICHER | +- | +
| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Welcher spezifische Token-Typ wird verwendet (JWT, opaque tokens, session cookies)? | +JWT mit HS256-Algorithmus, 5 Minuten Access Token, 7 Tage Refresh Token | +✅ SICHER | +- | +
| Wo werden Token im Backend gespeichert (Redis, Datenbank, im Speicher)? | +Stateless JWT-Implementierung, keine persistenten Token im Backend | +✅ SICHER | +- | +
| Zeigen Sie die tatsächliche Token-Struktur und welche Claims sie enthält. | +JWT-Claims: sub (username), mandateId, userId, authenticationAuthority, jti (token ID), sid (session ID), exp (expiration) | +✅ SICHER | +- | +
| Demonstrieren Sie den Token-Revocation-Mechanismus - wie schnell können alle Benutzer-Sessions beendet werden? | +Umfassende Revocation über Admin-Interface (routeSecurityAdmin.py): pro User, Session, Token-ID und Mandate - sofort möglich | +✅ IMPLEMENTIERT | +- | +
| Was passiert mit bestehenden Token, wenn ein Benutzer sein Passwort ändert? | +Automatische Token-Invalidierung implementiert. Alle bestehenden Token werden bei Passwort-Änderung oder -Reset sofort widerrufen. | +✅ IMPLEMENTIERT | +- | +
| Was sind die genauen Timeout-Werte für Access- und Refresh-Token? | +Access Token: 5 Minuten, Refresh Token: 7 Tage | +✅ KONFIGURIERT | +- | +
| Wie ist Token-Refresh implementiert - automatisch oder manuell? | +Automatischer Refresh über TokenRefreshMiddleware und ProactiveTokenRefreshMiddleware | +✅ IMPLEMENTIERT | +- | +
| Können Sie den Code zeigen, wo Token-Validierung im Backend stattfindet? | +Implementiert in modules/security/auth.py, _getUserBase() Funktion | +✅ IMPLEMENTIERT | +- | +
| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Gehen Sie den genauen Authentifizierungs-Flow vom Login zum authentifizierten API-Aufruf durch. | +Login → JWT-Erstellung → httpOnly Cookie → API-Aufruf mit Cookie/Header → Token-Validierung | +✅ IMPLEMENTIERT | +- | +
| Welche spezifischen Header sind für authentifizierte Anfragen erforderlich? | +Authorization: Bearer Token oder httpOnly Cookie (bevorzugt) | +✅ IMPLEMENTIERT | +- | +
| Wie unterscheiden sich API-Schlüssel zwischen Frontend-zu-Backend und Backend-zu-Backend-Aufrufen? | +Separate API-Schlüssel für verschiedene Services implementiert: OpenAI, Anthropic, Google, Microsoft, Tavily. Jeder Service hat eigene API-Keys in den Environment-Dateien. | +✅ IMPLEMENTIERT | +- | +
| Zeigen Sie ein Beispiel für Service-to-Service-Authentifizierung zwischen Blox-Komponenten. | +Keine BLOX-Komponenten gefunden. Die PowerOn App ist eine monolithische Anwendung mit modularen Services (ServiceCenter, Connectors). Service-to-Service erfolgt über interne Interfaces. | +✅ N/A | +- | +
| Was sind die spezifischen Rate Limits pro Endpoint? | +Login (30/min), Connections (30/min), Admin (30/min), Token-Revocation (10/min), Refresh (10/min). Kritische Endpoints sind geschützt. | +✅ IMPLEMENTIERT | +- | +
| Wo ist Rate Limiting implementiert (API Gateway, Anwendungsebene, WAF)? | +Anwendungsebene mit slowapi-Limiter | +✅ IMPLEMENTIERT | +- | +
| Wie werden Rate Limit-Verletzungen behandelt und protokolliert? | +HTTP 429 Fehler, Logging über Standard-Logger | +✅ IMPLEMENTIERT | +- | +
| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Wo genau werden folgende gespeichert: Datenbankverbindungsstrings, API-Schlüssel für Drittanbieter, JWT-Signierungsschlüssel, Verschlüsselungsschlüssel für ruhende Daten? | +Verschlüsselt in .env-Dateien mit Fernet-Verschlüsselung und umgebungs-spezifischen Master-Keys | +✅ SICHER | +- | +
| Zeigen Sie die Konfigurationsdateien - sind Geheimnisse hardcodiert? | +Keine hardcodierten Geheimnisse, alle verschlüsselt mit DEV_ENC:/PROD_ENC: Präfixen | +✅ SICHER | +- | +
| Wie wird der Master-Verschlüsselungsschlüssel geschützt und wo wird er gespeichert? | +Master-Key in separater Datei oder Umgebungsvariable, abgeleitet mit PBKDF2 | +✅ SICHER | +- | +
| Zeigen Sie den Beweis, dass Dev und Prod verschiedene verwenden: Datenbankzugangsdaten, API-Schlüssel, JWT-Signierungsschlüssel, Verschlüsselungsschlüssel. | +Verschiedene Master-Keys und verschlüsselte Secrets für alle Umgebungen (dev, int, prod) | +✅ SICHER | +- | +
| Wie werden Produktions-Geheimnisse bereitgestellt, ohne dass Entwickler Zugriff darauf haben? | +Entwickler erstellen und verwalten die Produktions-Secrets selbst. Keine Trennung erforderlich, da Entwickler die Secrets für die App-Entwicklung benötigen. | +✅ ANGEMESSEN | +- | +
| Können Sie demonstrieren, dass die Verwendung eines Produktions-API-Schlüssels in der Dev-Umgebung fehlschlägt? | +Umgebungsvalidierung implementiert - Secrets werden pro Umgebung mit verschiedenen Master-Keys entschlüsselt | +✅ IMPLEMENTIERT | +- | +
| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Wie authentifizieren sich Blox-Komponenten untereinander - zeigen Sie den tatsächlichen Mechanismus | +N/A - Keine BLOX-Komponenten: Die PowerOn App ist eine monolithische Anwendung. Interne Komponenten authentifizieren sich über Interface-basierte Mechanismen mit getInterface() Funktion. | +✅ N/A | +- | +
| Was verhindert, dass Komponente A direkt auf Daten von Komponente B in der Datenbank zugreift? | +N/A - Keine BLOX-Komponenten: Mandate-basierte Datenisolation über _uam() Funktion. Jede Datenbankabfrage wird durch Access Control gefiltert. | +✅ N/A | +- | +
| Zeigen Sie die Netzwerkrichtlinien oder Firewall-Regeln zwischen Blox-Microservices | +N/A - Keine BLOX-Komponenten: Monolithische Anwendung - keine Netzwerkrichtlinien zwischen internen Komponenten erforderlich. | +✅ N/A | +- | +
| Wie wird verhindert, dass eine kompromittierte Blox-Komponente auf andere zugreift? | +N/A - Keine BLOX-Komponenten: Interface-basierte Zugriffskontrolle und Mandate-Isolation. Jede Komponente hat nur Zugriff auf ihre zugewiesenen Daten. | +✅ N/A | +- | +
| Verfolgen Sie ein sensibles Datenfeld durch mehrere Blox-Komponenten - wie wird es in jedem Schritt geschützt? | +N/A - Keine BLOX-Komponenten: Daten werden durch _uam() Funktion in jedem Interface-Aufruf gefiltert und durch Access Control geschützt. | +✅ N/A | +- | +
| Welche Blox-Komponenten haben Datenbankzugriff und welche verwenden nur APIs? | +N/A - Keine BLOX-Komponenten: Alle Komponenten verwenden Interface-basierte APIs. Direkter Datenbankzugriff nur über interfaceAppModel.py. | +✅ N/A | +- | +
| Zeigen Sie das Datenfluss-Diagramm mit Sicherheitskontrollen an jeder Grenze | +N/A - Keine BLOX-Komponenten: Interface-basierte Architektur mit _uam() Filterung an jeder Datenbankabfrage. Mandate-Isolation auf Datenbankebene. | +✅ N/A | +- | +
| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Welche spezifischen Sicherheitsereignisse werden protokolliert: Fehlgeschlagene Login-Versuche, Berechtigungsverweigerungsfehler, Token-Validierungsfehler, Datenzugriffsmuster? | +Umfassendes Audit-Logging implementiert in auditLogger.py für alle Sicherheitsereignisse: Key-Access, User-Access, Data-Access, Security-Events | +✅ IMPLEMENTIERT | +- | +
| Zeigen Sie tatsächliche Log-Einträge für Sicherheitsereignisse. | +Strukturiertes Audit-Log mit Kategorien und detaillierten Einträgen für alle Sicherheitsereignisse | +✅ IMPLEMENTIERT | +- | +
| Wo werden Logs gespeichert und wie lange? | +Tägliche Rotation, 5 Backup-Dateien, 10MB pro Datei, konfigurierbar über APP_CONFIG | +✅ KONFIGURIERT | +- | +
| Können Sie demonstrieren, dass Logs keine sensiblen Daten enthalten (Passwörter, Token)? | +Logging-Filter sind implementiert (ChromeDevToolsFilter, HTTPDebugFilter, EmojiFilter). Keine explizite Token-Filterung gefunden, aber auch keine Hinweise auf Token-Exposition in den Logs. | +✅ SICHER | +- | +
| Zeigen Sie die Alarmkonfiguration für kritische Sicherheitsereignisse. | +Keine automatischen Alarme implementiert - dies ist eine empfohlene Verbesserung | +⚠️ NICHT IMPLEMENTIERT | +Implementierung von Security Monitoring Dashboard | +
| Wie schnell werden Sicherheitsteams über potenzielle Verletzungen benachrichtigt? | +Keine automatischen Benachrichtigungen - manuelles Monitoring über Logs | +⚠️ NICHT IMPLEMENTIERT | +Implementierung von automatischen Alert-Systemen | +
| Frage | +Antwort | +Resultat-Status | +Maßnahmen | +
|---|---|---|---|
| Wie schnell können Sie: Alle aktiven Sessions widerrufen, Alle API-Schlüssel rotieren, Ein kompromittiertes Benutzerkonto deaktivieren, Ein kompromittiertes Deployment zurücksetzen? | +Token-Revocation über Admin-Interface sofort möglich. API-Schlüssel-Rotation und Deployment-Rollback über Standard-Prozesse | +✅ IMPLEMENTIERT | +- | +
| Zeigen Sie die tatsächlichen Befehle/Verfahren für diese Operationen. | +Admin-Interface mit Token-Revocation-Funktionen. Standard-Deployment-Prozesse für Rollback | +✅ IMPLEMENTIERT | +- | +
| Wer hat Zugriff, um diese Notfallaktionen durchzuführen? | +Admin-Benutzer über das Admin-Interface. Deployment-Team für Rollback-Operationen | +✅ IMPLEMENTIERT | +- | +
Hohe Priorität:
+Mittlere Priorität:
+Die PowerOn App verfügt über eine professionelle und gut implementierte Sicherheitsarchitektur mit modernen Best Practices. Alle kritischen Sicherheitsaspekte sind vollständig implementiert.
+ +Kritische Sicherheitslücken: KEINE
+ Sicherheitsbewertung: ✅ SICHER
+ Empfehlung: Produktionsreif
Prioritäten für weitere Verbesserungen: Security Monitoring Dashboard, Security-Headers, Incident Response-Pläne.
+