1. erstelle ein Branch namens `feature/security` aus dem aktuellen `main` Branch. 2. erstelle eine Datei `FeatureRequests/FEATURE_PLAN-security.md` in der du die Umsetzungsaufgaben dokumentierst (siehe unten) und darin die TODO Liste erstellst und aktuallisierst. 3. Stelle mir Fragen bezüglich der Umsetzung 4. Verstehe, wie bisher im Frontend die UI aufgebaut ist (modular, keine inline css, globale app.css) 5. Implementiere die untenstehenden Aufgaben Schritt für Schritt. # FEATURE_REQUEST: Security — Server-seitige Sessions für Admin-API Umsetzungsaufgaben (konkret & eindeutig für KI / Entwickler) Die folgenden Aufgaben sind Schritt-für-Schritt auszuführen. Jede Aufgabe enthält das gewünschte Ergebnis und minimalen Beispielcode oder Befehle. Die KI/Entwickler sollen die Änderungen als Code-Patches anlegen, Tests hinzufügen und die Dokumentation aktualisieren. 1) Session-Store & Session-Konfiguration - Ziel: Server-seitige Sessions für Admin-Login verfügbar machen. - Schritte: - Installiere Packages: `npm install express-session connect-sqlite3 --save` (Backend). - In `backend/src/server.js` (oder Entrypoint) konfiguriere `express-session` mit `connect-sqlite3`: ```js const session = require('express-session'); const SQLiteStore = require('connect-sqlite3')(session); app.use(session({ store: new SQLiteStore({ db: 'sessions.sqlite' }), secret: process.env.ADMIN_SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'Strict', maxAge: 8*60*60*1000 } })); ``` - Abnahme: Session-Cookie (`sid`) wird gesetzt nach Login, cookie-Flags korrekt. 2) Login-Endpoint (Admin) - Ziel: Admin kann sich mit Benutzername/Passwort anmelden; Backend erstellt Session. - Schritte: - Füge `POST /auth/login` hinzu, prüft Credentials (z. B. gegen environment-stored admin user/pass oder htpasswd), legt `req.session.user = { role: 'admin' }` an und `req.session.csrfToken = randomHex()` an. - Rückgabe: 200 OK. Cookie wird automatisch gesetzt (`credentials: 'include'` vom Frontend). - Abnahme: Nach `POST /auth/login` existiert `req.session.user` und `req.session.csrfToken`. 3) CSRF-Endpoint + Middleware - Ziel: Session-gebundenen CSRF-Token ausgeben und Requests schützen. - Schritte: - Endpoint `GET /auth/csrf-token` gibt `{ csrfToken: req.session.csrfToken }` zurück (nur wenn eingeloggt). - Middleware `requireCsrf` prüft `req.headers['x-csrf-token'] === req.session.csrfToken` für state-changing Methoden. - Abnahme: state-changing Admin-Requests ohne oder mit falschem `X-CSRF-Token` bekommen `403`. 4) Backend-Auth-Middleware für Admin-API - Ziel: Alle `/api/admin/*` Endpoints prüfen Session statt Client-Token. - Schritte: - Ersetze oder erweitere bestehende Admin-Auth-Middleware (`middlewares/auth.js`) so, dass sie `req.session.user && req.session.user.role === 'admin'` prüft; falls nicht gesetzt → `403`. - Abnahme: `GET /api/admin/*` ohne Session → `403`; mit gültiger Session → durchgelassen. 5) Frontend-Änderungen (adminApi) - Ziel: Frontend sendet keine Admin-Bearer-Tokens mehr; verwendet Cookie-Session + CSRF-Header. - Schritte: - Entferne in `frontend/src/services/adminApi.js` die Abhängigkeit von `process.env.REACT_APP_ADMIN_API_KEY`. - Passe `adminFetch`/`adminRequest` an: bei Requests setze `credentials: 'include'` und füge `X-CSRF-Token` Header (Token bezieht Frontend über `GET /auth/csrf-token` nach Login). - Dokumentiere in `frontend/README` oder Code-Kommentar, dass Admin-UI nach Login `fetch('/auth/csrf-token', { credentials: 'include' })` aufruft. - Abnahme: `adminApi.js` sendet keine Bearer-Header; admin Requests beinhalten `credentials: 'include'` und `X-CSRF-Token`. 6) Entfernen von Admin-Key aus Frontend Build/Compose/Dockerfile - Ziel: Keine Weitergabe von `ADMIN_API_KEY` an `frontend` und kein Kopieren sensibler `.env` in Frontend-Image. - Schritte: - Entferne Zeile `- REACT_APP_ADMIN_API_KEY=${ADMIN_API_KEY}` aus `docker/prod/docker-compose.yml`. - Entferne `COPY docker/prod/frontend/config/.env ./.env` aus `docker/prod/frontend/Dockerfile` oder stelle sicher, dass diese Datei ausschließlich non-sensitive Keys enthält. - Dokumentiere in `FeatureRequests/FEATURE_REQUEST-security.md` welche Keys im runtime-`env.sh` erlaubt sind (z. B. `API_URL`, `APP_VERSION`). - Abnahme: `docker-compose` enthält keine Übergabe an `frontend`; Build und Image enthalten keine Production-Secrets. 7) Secrets-Handling / Deployment - Ziel: Secrets nur in Backend-Umgebung bereitstellen. - Schritte: - Setze `ADMIN_API_KEY` und `ADMIN_SESSION_SECRET` in CI/CD Secrets oder Docker Secrets und referenziere sie nur im `backend` Service. - Beispiel-Dokumentation für CI: wie man Secret in GitLab/GitHub Actions setzt und an Container übergibt. - Abnahme: Secrets sind nicht in Repo/Images; `docker inspect` der frontend-Container zeigt keinen Admin-Key. 8) Tests & CI-Checks - Ziel: Automatisierte Verifikation der Sicherheitsregeln. - Schritte: - Integrationstest 1: `GET /api/admin/some` ohne Session → expect 403. - Integrationstest 2: `POST /auth/login` with admin credentials → expect Set-Cookie; then `GET /auth/csrf-token` → receive token; then `POST /api/admin/action` with `X-CSRF-Token` → expect 200. - Build-scan-Check: CI Schritt `rg REACT_APP_ADMIN_API_KEY build/ || true` fails if found. - Abnahme: Tests grün; CI verweigert Merge wenn Build enthält Admin-Key. 9) Key-Leak Reaktion (konkrete Anweisungen) - Ziel: Falls ein Admin-Key geleakt wurde, sichere, koordinierte Rotation. - Schritte: - Scannen: `trufflehog --regex --entropy=True .` oder `git-secrets scan`. - Entfernen: `git-filter-repo --replace-text passwords.txt` oder `bfg --replace-text passwords.txt` (siehe docs). - Rotation: Erzeuge neuen Key (openssl rand -hex 32), update CI secret, redeploy Backend. - Hinweis: History-Rewrite ist invasiv; kommuniziere mit Team und informiere Contributors. 10) Dokumentation - Ziel: Abschlussdokumentation aktualisiert. - Schritte: - Ergänze `AUTHENTICATION.md` um Login/Session/CSRF-Flow und Secret-Handling. - Ergänze `FeatureRequests/FEATURE_REQUEST-security.md` mit Implementations-Links (Patches/PRs). 11) MIGRATION-GUIDE Anpassung (unbedingt) - Ziel: Die `frontend/MIGRATION-GUIDE.md` spiegelt nicht mehr den sicheren Produktions-Workflow. Sie muss aktualisiert werden, damit Entwickler/KI keine unsicheren Anweisungen (Admin-Key im Frontend) ausführen. - Aktueller Stand (zu prüfen): Die MIGRATION-GUIDE enthält Anweisungen, `REACT_APP_ADMIN_API_KEY` in `frontend/.env` zu setzen und dieselbe Variable an `frontend` im `docker-compose.yml` weiterzugeben. Dies steht im direkten Widerspruch zur hier geforderten serverseitigen Session-Lösung. - Erforderliche Änderungen in `frontend/MIGRATION-GUIDE.md` (konkret): - Entferne oder ersetze alle Anweisungen, die `REACT_APP_ADMIN_API_KEY` in Frontend `.env` oder Build-Umgebungen für Production setzen. - Ersetze Fetch-/Axios-Beispiele, die `Authorization: Bearer ${process.env.REACT_APP_ADMIN_API_KEY}` setzen, durch die neue Anleitung: Login → `GET /auth/csrf-token` → `fetch(..., { credentials: 'include', headers: { 'X-CSRF-Token': csrfToken } })`. - Passe das Docker-Beispiel an: `ADMIN_API_KEY` darf nur dem `backend`-Service übergeben werden; entferne die Weitergabe an `frontend` (Zeile `- REACT_APP_ADMIN_API_KEY=${ADMIN_API_KEY}`). - Ersetze lokale Testanweisungen, die Frontend mit `REACT_APP_ADMIN_API_KEY` starten, durch Login-/Session-Testschritte (siehe Tasks 2/3/8). - Ergänze Hinweis zur CI/Build-Scan-Prüfung: CI muss prüfen, dass gebaute `build/` keine Admin-Key-Strings enthält. - Abnahme: `frontend/MIGRATION-GUIDE.md` enthält keine Production-Anweisungen, die Admin-Secrets ins Frontend bringen; stattdessen ist der Session-Flow dokumentiert und verlinkt. Hinweis für die Implementierung - Ergänze in `FeatureRequests/FEATURE_REQUEST-security.md` einen Link/Verweis zur überarbeiteten MIGRATION-GUIDE-Version in der PR/Release-Notes, damit Reviewer die Änderung nachvollziehen können. Rolle der implementierenden KI/Dev - Erzeuge konkrete Code-Patches, führe lokale Tests aus, öffne PR mit Änderungen und Tests. - Stelle sicher, dass alle Abnahme-Kriterien (oben) automatisiert oder manuell prüfbar sind. Mit diesen Aufgaben sind die vorher offenen Fragen in eindeutige, ausführbare Schritte übersetzt. Bitte bestätige, welche Aufgaben ich automatisch umsetzen soll (z. B. `1` = Compose/Docker-Änderungen; `2` = Frontend `adminApi.js` Patch; `3` = Backend Session+CSRF minimal-Implementierung; oder `all`). Hintergrund (Ist-Stand) - Aktuell existieren folgende sicherheitskritische Zustände im Repository: - `frontend/.env` enthält `REACT_APP_ADMIN_API_KEY` in der Arbeitskopie (lokal). Die Datei ist in `.gitignore` und wird nicht ins Git-Repository getrackt, ist aber sensibel und darf nicht in Builds/Images gelangen. - `docker/prod/docker-compose.yml` injiziert `REACT_APP_ADMIN_API_KEY=${ADMIN_API_KEY}` in den `frontend`-Service — der Key kann so in den gebauten Frontend-Bundles landen. - `frontend/src/services/adminApi.js` liest `process.env.REACT_APP_ADMIN_API_KEY` und sendet den Bearer-Token clientseitig mit Admin-Requests. - Das Production-Frontend-Dockerfile kopiert `docker/prod/frontend/config/.env` in das Laufzeit-Image und führt zur Startzeit ein `env.sh` aus, das `env-config.js` erzeugt (`window._env_`), was sensible Werte im Browser verfügbar machen kann, falls sie in `.env` landen. - Die Moderation-Weboberfläche ist zusätzlich durch `htpasswd`/nginx HTTP Basic Auth geschützt — das schützt das UI, aber nicht die API-Endpoints ausreichend. Problemstellung (warum es ein Problem ist) - Ein im Frontend sichtbarer Admin-Key ist öffentlich und ermöglicht Missbrauch (API-Calls mit Admin-Rechten von jedem Browser). - Das serverseitige Secret `ADMIN_API_KEY` wird derzeit in Artefakte/Images injiziert und kann geleakt werden. - HTTP Basic Auth vor der UI ist nützlich, aber kein Ersatz für serverseitige API-Authentifizierung; API-Endpunkte müssen eigenständig prüfen. Ziel (Soll-Stand, aus Kundensicht) - Admin-Funktionen sind nur nach sicherer Anmeldung erreichbar. - Der geheime Admin-Key verbleibt ausschließlich auf dem Server/Backend und wird nicht in Frontend-Code, Images oder öffentlich zugängliche Dateien geschrieben. - Frontend kommuniziert nach Anmeldung mit dem Backend, ohne je den Admin-Key im Browser zu speichern. Anforderungen (aus Sicht des Auftraggebers, umsetzbar durch eine KI) - Authentifizierung: - Einführung eines serverseitigen Login-Flows für Admins (Session-Cookies, HttpOnly, Secure, SameSite). - Nach erfolgreicher Anmeldung erhält der Admin-Browser ein HttpOnly-Cookie; dieses Cookie erlaubt Zugriff auf geschützte `/api/admin/*`-Endpoints. - Backend validiert alle `/api/admin/*`-Requests anhand der Session; nur dann wird mit dem internen `ADMIN_API_KEY` gearbeitet. - Secrets & Build: - Keine Secrets (z. B. `ADMIN_API_KEY`) im Frontend-Quellcode, in `frontend/.env`, in `env-config.js` oder in gebauten Bundles. - `docker/prod/docker-compose.yml` darf `ADMIN_API_KEY` nur dem `backend`-Service bereitstellen; keine Weitergabe an `frontend`. - `Dockerfile` des Frontends darf keine Produktion-`.env` kopieren, die Secrets enthält. - Betrieb & Infrastruktur: - Bestehende `htpasswd`-Absicherung der Admin-UI kann beibehalten werden als zusätzliche Hürde, ist aber nicht die einzige Schutzmaßnahme. - Empfehlung: `ADMIN_API_KEY` über sichere Secret-Mechanismen bereitstellen (CI/CD secret store, Docker Secrets, Swarm/K8s Secrets) — dies ist ein Hinweis, keine Pflichtanweisung. Akzeptanzkriterien (klar messbar, für Tests durch eine KI/Dev) - Funktional: - Unauthentifizierte Requests an `/api/admin/*` erhalten `403 Forbidden`. - Admin-Login-Endpoint existiert und setzt ein HttpOnly-Cookie; angemeldete Admins erreichen `/api/admin/*` erfolgreich. - Artefakte / Repo: - `frontend`-Bundle (der gebaute `build/`-Ordner) enthält nicht den Wert von `ADMIN_API_KEY` (automatischer Scan: kein Vorkommen des Key-Strings). - `frontend/.env` enthält keine `REACT_APP_ADMIN_API_KEY`-Zeile in Produktion; `docker/prod/docker-compose.yml` enthält keine Weitergabe des Keys an `frontend`. - Sicherheit & Ops: - Dokumentation: In `AUTHENTICATION.md` und in dieser Feature-Request-Datei wird der neue Login-Flow und Hinweis zum Secret-Handling vermerkt. - Dokumentation: In `AUTHENTICATION.md` und in dieser Feature-Request-Datei wird der neue Login-Flow und Hinweis zum Secret-Handling vermerkt. - Falls ein Key im Git-Verlauf existierte, ist die Rotation des Admin-Keys als Handlungsempfehlung dokumentiert. - Falls `frontend/.env` oder ein Admin-Key jemals in das Repository gelangt ist: Scannt die Git-History und entfernt das Secret aus der History, danach rotiert den Key. Empfohlene Tools/Schritte (kurz): - Finden: `git log --all -S 'part-of-key'` oder `git grep -n "REACT_APP_ADMIN_API_KEY" $(git rev-list --all)` oder nutzen `truffleHog`/`git-secrets`. - Entfernen aus History: `git-filter-repo` oder `bfg-repo-cleaner` (z.B. `bfg --replace-text passwords.txt --no-blob-protection`) — danach Force-Push in ein neues Remote (Achtung: Auswirkungen auf Contributors). - Key-Rotation: Erzeuge neuen `ADMIN_API_KEY`, setze ihn in der sicheren Backend-Umgebung (CI/CD secrets / Docker secret), redeploye Backend. - Hinweis: Diese Schritte sind invasiv für die Git-History; koordinieren mit Team bevor Ausführung. Nicht-funktionale Anforderungen - Use Session-Cookies: Cookies müssen `HttpOnly`, `Secure` und `SameSite=Strict` (oder Lax falls nötig) gesetzt werden. - CSRF-Schutz: Bei Cookie-basierten Sessions muss ein CSRF-Schutzmechanismus vorhanden sein (z. B. double-submit-token oder CSRF-Header). Hinweis: CSRF-Mechanik ist zu implementieren, aber detaillierte Schritte sind nicht Teil dieses Requests. - Kompatibilität: Änderungen dürfen Entwickler-Workflows nicht unnötig blockieren; Dev-Mode-Patterns (runtime `env-config.js` in `docker/dev`) können bestehen bleiben, jedoch klar getrennt von Prod. Hinweise für die implementierende KI / das Dev-Team (kontextbezogen) - Aktueller Code-Pfade von Relevanz: - `frontend/src/services/adminApi.js` — liest aktuell `process.env.REACT_APP_ADMIN_API_KEY` und setzt den Bearer-Token clientseitig. - `frontend/.env` — enthält aktuell `REACT_APP_ADMIN_API_KEY`. - `docker/prod/docker-compose.yml` — injiziert `REACT_APP_ADMIN_API_KEY=${ADMIN_API_KEY}` in `frontend`. - `docker/prod/frontend/Dockerfile` — kopiert `docker/prod/frontend/config/.env` in das Image und führt `env.sh` aus, das `env-config.js` erzeugt (`window._env_`). - `docker/prod/frontend/config/env.sh` — generiert zur Laufzeit `env-config.js` aus `.env`. - `docker/prod/frontend/config/htpasswd` — existierender Schutz der Admin-UI via nginx. - Erwartung an eine KI-Implementierung: - Verstehe die Codebasis (insbesondere `frontend/src/*` und `backend/src/*`) und identifiziere alle Stellen, die `REACT_APP_ADMIN_API_KEY` oder `ADMIN_API_KEY` verwenden oder weiterreichen. - Entferne clientseitige Verwendung des Admin-Keys; ersetze Aufrufe an Admin-API so, dass sie serverseitig autorisiert werden (Session-Check). - Verifiziere durch automatische Tests (Integrationstest oder API-Call) dass `/api/admin/*` ohne Session abgewiesen wird und mit Session funktioniert. Was der Auftraggeber (Ich) erwartet — kurz und klar - Die Admin-Funktionen sind nur nach Anmeldung verfügbar. - Keine Admin-Secrets gelangen in Frontend-Bundles, Images oder öffentlich zugängliche Dateien. - Der existierende `htpasswd`-Schutz darf bestehen bleiben, ist aber nicht alleinige Sicherheitsmaßnahme. Abnahmekriterien (für das Review durch den Auftraggeber) - Manuelle Überprüfung: Versuch, Admin-Endpoints ohne Login aufzurufen → `403`. - Build-Review: gebaute Frontend-Dateien enthalten keinen Admin-Key. - Dokumentation aktualisiert (`AUTHENTICATION.md` weist auf neue Session-Flow hin). Offene Fragen / Optionen (für Entwickler/KI) — Empfehlung und Umsetzungsdetails - Session-Store (empfohlen: SQLite für Single-Host, Redis für Skalierung) - Empfehlung für diese App: **SQLite / file-basierter Session-Store** (einfach zu betreiben, keine zusätzliche Infrastruktur). - Umsetzung (Express): benutze `express-session` + `connect-sqlite3` (oder `better-sqlite3` backend). Konfiguration: - Session-Cookie: `HttpOnly`, `Secure` (Prod), `SameSite=Strict` (oder `Lax` wenn externe callbacks nötig), `maxAge` angemessen (z. B. 8h). - Session-Secret aus sicherer Quelle (Backend `ADMIN_SESSION_SECRET`), nicht im Repo. - Skalierung: falls Cluster/Multiple hosts geplant, wechsle zu **Redis** (z.B. `connect-redis`) und setze Redis via Docker/K8s Secret. - CSRF-Mechanik (empfohlen: session-bound CSRF token + Header) - Empfehlung: Implementiere einen session-gebundenen CSRF-Token. Ablauf: 1. Bei Login: generiere `req.session.csrfToken = randomHex()` auf dem Server. 2. Exponiere Endpoint `GET /auth/csrf-token` (nur für eingeloggte Sessions), der das Token im JSON zurückgibt. 3. Frontend ruft `/auth/csrf-token` nach Login (`credentials: 'include'`) und speichert Token im JS-Scope. 4. Bei state-changing Requests sendet Frontend `X-CSRF-Token: ` Header. 5. Server-Middleware vergleicht Header mit `req.session.csrfToken` und verwirft bei Mismatch (403). - Vorteil: HttpOnly-Session-Cookie bleibt geschützt; Token ist an Session gebunden. - Alternative (schnell): Double-submit cookie (weniger robust, Token in non-HttpOnly cookie + Header); nur als kurzfristige Übergangslösung. - Entfernen von Admin-Key aus Frontend/Build (konkrete Änderungen) - `frontend/src/services/adminApi.js`: entferne Nutzung von `process.env.REACT_APP_ADMIN_API_KEY`. Passe `adminRequest` so an, dass `credentials: 'include'` verwendet wird und kein Bearer-Token gesetzt wird. - `docker/prod/docker-compose.yml`: lösche die Zeile `- REACT_APP_ADMIN_API_KEY=${ADMIN_API_KEY}` unter `frontend`. - `docker/prod/frontend/Dockerfile`: entferne `COPY docker/prod/frontend/config/.env ./.env` (oder stelle sicher, dass die Datei keine Secrets enthält). Vermeide Prod `.env` Kopie in Image. - `docker/prod/frontend/config/env.sh`: darf nur non-sensitive Werte (z. B. `API_URL`, `APP_VERSION`) schreiben; dokumentiere welche Keys erlaubt sind. - Secrets-Delivery / Deployment - Backend-Secret `ADMIN_API_KEY` und `ADMIN_SESSION_SECRET` via CI/CD Secret Store oder Docker Secrets bereitstellen. - Beispiel (Docker secret): erstelle Secret im Swarm/K8s und referenziere es nur im `backend`-Service. - Tests / Abnahme (automatisierbar) - Integrationstest 1: `GET /api/admin/*` ohne Session → `403`. - Integrationstest 2: Login-Flow → setze Session-Cookie → `POST /api/admin/*` mit gültigem `X-CSRF-Token` → `200`. - Build-Scan: nach Build `grep -R "" build/` oder `rg REACT_APP_ADMIN_API_KEY build/` → kein Treffer. - Key-Leak Reaktion - Falls Key geleakt: sofort Key-Rotation, dokumentiere wie (generate new key, update backend secret, redeploy), und führe Git-History-Check wie in Abschnitt oben durch. - Operationale Hinweise - Behalte `htpasswd`-Schutz für Admin-UI als zusätzliche Zugangskontrolle, nicht als einzige Schutzmaßnahme. - Dokumentiere alle Änderungen in `AUTHENTICATION.md` und in Release-Notes. Diese Empfehlungen sind aus Sicht einer sicheren, pragmatischen Umsetzung gewählt: sie minimieren Infrastruktur-Overhead (SQLite) und bieten klare, testbare CSRF/Session‑Mechaniken. Eine implementierende KI soll die obenstehenden Punkte in konkreten Code‑Patches umsetzen und automatisierte Tests hinzufügen. Kontakt / Kontext - Repo: Project-Image-Uploader — bestehende Struktur `docker/prod`, `frontend/`, `backend/` beachten. - Hinweis: Diese Feature-Request-Datei benennt Missstände und Anforderungen; sie erwartet, dass ein Entwickler oder eine KI die Implementierung auf Code-Ebene vornimmt. ---