feat: implement security headers and rate limiting; update environment variables and documentation
This commit is contained in:
@@ -214,6 +214,63 @@ recept.gynther.se {
|
||||
|
||||
---
|
||||
|
||||
## Säkerhetshuvuden
|
||||
|
||||
Säkerhetshuvuden är implementerade i tre lager för djupförsvar:
|
||||
|
||||
### Lager 1: Caddy (globalt för alla tjänster)
|
||||
|
||||
Sätts i `(common)`-blocket och gäller alla domäner som importerar det.
|
||||
|
||||
| Header | Värde | Syfte |
|
||||
|--------|-------|-------|
|
||||
| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains; preload` | Tvingar HTTPS, skyddar mot protocol downgrade |
|
||||
| `X-Content-Type-Options` | `nosniff` | Förhindrar MIME-sniffing |
|
||||
| `X-Frame-Options` | `DENY` | Skyddar mot clickjacking |
|
||||
| `X-XSS-Protection` | `1; mode=block` | Legacy XSS-skydd (äldre webbläsare) |
|
||||
| `Referrer-Policy` | `strict-origin-when-cross-origin` | Begränsar referrer-läckage |
|
||||
| `Permissions-Policy` | `geolocation=(), microphone=(), camera=(), payment=()` | Inaktiverar känsliga webbläsar-API:er |
|
||||
| `Cross-Origin-Opener-Policy` | `same-origin` | Isolerar browsing context |
|
||||
| `Cross-Origin-Resource-Policy` | `same-origin` | Förhindrar cross-origin läsning av resurser |
|
||||
| `Cross-Origin-Embedder-Policy` | `require-corp` | Kräver explicit cross-origin permission |
|
||||
|
||||
### Lager 2: NestJS Helmet (backup)
|
||||
|
||||
Helmet konfigurerat i `backend/src/main.ts` som säkerhetsbackup ifall Caddy kringgås eller misslyckas. CSP är inaktiverat i Helmet (`contentSecurityPolicy: false`) eftersom det hanteras av Next.js.
|
||||
|
||||
```
|
||||
Aktiveras vid: docker compose up --build backend
|
||||
```
|
||||
|
||||
### Lager 3: Next.js Content Security Policy
|
||||
|
||||
CSP sätts i `frontend/next.config.js` via `headers()`-funktionen och gäller alla routes (`/:path*`).
|
||||
|
||||
| Direktiv | Tillåtna källor | Motivering |
|
||||
|----------|----------------|------------|
|
||||
| `default-src` | `'self'` | Restriktiv default |
|
||||
| `script-src` | `'self' 'unsafe-eval' 'unsafe-inline'` | Krävs av Next.js runtime |
|
||||
| `style-src` | `'self' 'unsafe-inline' fonts.googleapis.com` | Inline-stilar + Google Fonts |
|
||||
| `img-src` | `'self' data: https:` | Tillåter externa bilder via HTTPS |
|
||||
| `font-src` | `'self' fonts.gstatic.com` | Google Fonts-filer |
|
||||
| `connect-src` | `'self' api.mistral.ai` | API-anrop inkl. Mistral AI |
|
||||
| `frame-src` | `'none'` | Inga inbäddade frames tillåtna |
|
||||
| `object-src` | `'none'` | Inga plugins (Flash, etc.) |
|
||||
| `base-uri` | `'self'` | Skyddar mot base-tag-injektion |
|
||||
| `form-action` | `'self'` | Formulär får bara posta till samma origin |
|
||||
|
||||
> **Notering:** `'unsafe-eval'` och `'unsafe-inline'` i `script-src` är nödvändiga för Next.js 16 med App Router. Undvik att ta bort dessa utan noggrann testning.
|
||||
|
||||
### Felsökning av CSP-brott
|
||||
|
||||
Om en funktion slutar fungera efter CSP-aktivering:
|
||||
1. Öppna webbläsarens devtools → Console för att se CSP-felmeddelanden
|
||||
2. Kontrollera vilken domän/resurs som blockeras
|
||||
3. Lägg till domänen i rätt direktiv i `frontend/next.config.js`
|
||||
4. Vanliga undantag: WebSockets kräver `wss:` i `connect-src`, Service Workers kräver `worker-src 'self'`
|
||||
|
||||
---
|
||||
|
||||
## Arkitekturprincip: API routes framför Server Actions
|
||||
|
||||
> **Regel: Använd Next.js API routes (`/app/api/...`) för all mutation från klientkomponenter. Använd INTE Server Actions för detta.**
|
||||
|
||||
Reference in New Issue
Block a user