security: Härtung der CMS-API + Deployment
App-Level: - Security-Header (secureHeaders) global; /images/* mit strikter CSP+sandbox → bösartiges SVG kann kein JS im Origin ausführen - Body-Limit 256 KB auf /api/*; Login-Rate-Limit (10/5min) gegen Brute-Force - Upload: 8-MB-Limit + Format-Verifikation (sharp-Metadaten, SVG/GIF-Signatur) - Comment-Längenlimit (10k) gegen DB-Bloat - DB-Fehler nicht mehr roh ausliefern (serverError-Helper) - Profil-PUT koalesziert Hugo-Builds (kein Build-Sturm) Infra: - Container läuft non-root (USER node, uid 1000) + Proxmox-Repo-chown - Ports binden per Default auf 127.0.0.1 (BIND_ADDR-Escape-Hatch) - Kong-CORS auf SITE_URL beschränkt statt "*" - README: Härtungs- + Migrationshinweise Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+37
-2
@@ -72,8 +72,11 @@ Fragt interaktiv nur Storage/Bridge/IP ab (Enter = Default). Kein Token nötig.
|
||||
2. `POSTGRES_PASSWORD` + `JWT_SECRET` setzen: je `openssl rand -hex 32`
|
||||
3. Keys ableiten: `node scripts/generate-keys.mjs` → `ANON_KEY` + `SERVICE_ROLE_KEY` in `.env`
|
||||
4. `SITE_URL` + `API_EXTERNAL_URL` auf die LAN-/Domain-Adresse setzen
|
||||
5. `docker compose up -d --build` (Erststart: DB bootet + Schema/Migrations)
|
||||
6. Login-User anlegen (Self-Signup ist aus):
|
||||
5. `kong.yml`: Platzhalter `__CORS_ORIGIN__` durch `SITE_URL` (Browser-Origin) ersetzen
|
||||
6. `BIND_ADDR` in `.env`: `127.0.0.1` hinter Reverse-Proxy (Standard), `0.0.0.0` für LAN-Direktzugriff
|
||||
7. Repo dem Container-User (uid 1000) übereignen: `chown -R 1000:1000 <repo-root>`
|
||||
8. `docker compose up -d --build` (Erststart: DB bootet + Schema/Migrations)
|
||||
9. Login-User anlegen (Self-Signup ist aus):
|
||||
```
|
||||
source .env
|
||||
curl -X POST "$API_EXTERNAL_URL/auth/v1/admin/users" \
|
||||
@@ -89,6 +92,38 @@ Dann: Admin `…:8080/admin/` · Live `…:8080/` · Preview `…:8080/_preview/
|
||||
`cd admin && npm install && npm run dev` (Vite-Devserver, proxyt `/api` +
|
||||
`/_preview` an den laufenden Container auf :8080).
|
||||
|
||||
## Sicherheit / Härtung
|
||||
|
||||
Eingebaute Schutzmaßnahmen (Stand: Härtungs-Pass):
|
||||
|
||||
- **Sicherheits-Header** auf allen Antworten (X-Frame-Options, nosniff,
|
||||
Referrer-Policy, HSTS); Uploads unter `/images/*` mit strikter CSP +
|
||||
`sandbox` → ein bösartiges SVG kann kein JavaScript im Origin ausführen.
|
||||
- **Rate-Limit** auf `/api/auth/login` (10 Versuche/IP pro 5 Min) gegen Brute-Force.
|
||||
- **Body-Limit** 256 KB auf JSON-`/api/*`, Bild-Upload max. 8 MB mit
|
||||
Format-Verifikation (sharp-Metadaten bzw. SVG/GIF-Signatur).
|
||||
- **Comment-Limits** (Body ≤ 10 000 Zeichen) gegen DB-Bloat.
|
||||
- **Kein Info-Leak**: rohe DB-Fehler werden serverseitig geloggt, nach außen
|
||||
nur generische Meldungen.
|
||||
- **Non-root**: der CMS-Container läuft als `node` (uid 1000).
|
||||
- **Port-Binding** über `BIND_ADDR` (Standard `127.0.0.1`), DB nur auf localhost.
|
||||
- **CORS** am Kong-Gateway auf die eigene `SITE_URL`-Origin beschränkt (kein `*`).
|
||||
|
||||
### Migration eines bestehenden Containers
|
||||
|
||||
Bei `git pull` auf einer schon laufenden Instanz greifen drei Änderungen, die
|
||||
sonst einen frischen Deploy voraussetzen — **vor** dem nächsten
|
||||
`docker compose up -d --build` von Hand nachziehen:
|
||||
|
||||
1. **Non-root:** `chown -R 1000:1000 <repo-root>` — sonst kann Hugo `public/`
|
||||
nicht mehr bauen (Permission denied).
|
||||
2. **CORS:** `kong.yml` enthält jetzt `__CORS_ORIGIN__`; auf einem bereits
|
||||
initialisierten Container ersetzt das Proxmox-Script den Platzhalter nicht.
|
||||
Manuell auf die `SITE_URL` setzen, sonst werden alle Browser-API-Calls
|
||||
(inkl. Login) per CORS geblockt.
|
||||
3. **BIND_ADDR:** Key in `.env` ergänzen. Default `127.0.0.1` ist hinter einem
|
||||
TLS-Proxy korrekt; für LAN-Direktzugriff `0.0.0.0` setzen.
|
||||
|
||||
## API
|
||||
|
||||
Alle `/api/*` (ausser `/health`) verlangen `Authorization: Bearer <supabase-token>`.
|
||||
|
||||
Reference in New Issue
Block a user