Files
einundzwanzig-verein/.env.example
vk 058612dbe6 [P1 Security] Session Security Hardening – Encryption & Secure Cookies (vibe-kanban 48c2078b)
## Security Audit: Session-Konfiguration härten

### Problem
Die aktuelle `.env.example` hat unsichere Session-Defaults:

```env
SESSION_ENCRYPT=false      # Session-Daten unverschlüsselt in der DB
SESSION_SECURE_COOKIE=     # Nicht gesetzt – Cookie wird auch über HTTP gesendet
SESSION_DOMAIN=null         # Nicht eingeschränkt
```

Da die App eine Custom Nostr-basierte Auth verwendet (`app/Auth/NostrSessionGuard.php`) und der `pubkey` in der Session gespeichert wird, ist die Session ein attraktives Angriffsziel. Unverschlüsselte Sessions in der Datenbank bedeuten, dass ein DB-Leak sofort alle aktiven Sessions kompromittiert.

### Lösung

**1. `.env.example` aktualisieren:**

```env
SESSION_ENCRYPT=true
SESSION_SECURE_COOKIE=true
```

**2. Session-Config in `config/session.php` prüfen:**

Falls `config/session.php` nicht existiert (Laravel 12 Slim-Struktur), muss die Config ggf. mit `php artisan config:publish session` veröffentlicht werden. Prüfe ob die folgenden Werte korrekt gesetzt sind:

```php
'encrypt' => env('SESSION_ENCRYPT', true),        // Default auf true ändern
'secure' => env('SESSION_SECURE_COOKIE', true),    // Default auf true ändern
'http_only' => true,                                // Bereits Standard
'same_site' => 'lax',                               // Bereits Standard
```

**3. Cookie-Sicherheit:**
- `http_only` verhindert JavaScript-Zugriff auf Session-Cookies (Schutz gegen XSS-Cookie-Theft)
- `secure` erzwingt HTTPS-only Übertragung
- `same_site: lax` schützt gegen CSRF bei Top-Level-Navigation

### Betroffene Dateien
- `.env.example` – Default-Werte aktualisieren
- `config/session.php` – Falls vorhanden, Defaults härten. Falls nicht vorhanden, mit `php artisan config:publish session` erstellen und anpassen

### Vorgehen
1. Prüfe ob `config/session.php` existiert (bei Laravel 12 ist es möglicherweise nicht veröffentlicht)
2. Falls nicht vorhanden: `php artisan config:publish session --no-interaction`
3. Sichere Defaults setzen (encrypt=true, secure=true)
4. `.env.example` aktualisieren
5. Einen Pest-Test schreiben, der verifiziert dass Session-Cookies die korrekten Flags haben (secure, httpOnly, sameSite)
6. `vendor/bin/pint --dirty` und `php artisan test --compact`

### Hinweis
- In der lokalen Entwicklung (`APP_ENV=local`) kann `SESSION_SECURE_COOKIE=false` gesetzt werden, damit HTTP funktioniert
- Der Default in der Config sollte aber `true` sein, damit Produktion abgesichert ist
- Die `.env` Datei selbst wird NICHT bearbeitet (nur `.env.example`)

### Akzeptanzkriterien
- `SESSION_ENCRYPT=true` als Default in `.env.example`
- `SESSION_SECURE_COOKIE=true` als Default in `.env.example`
- Session-Config verwendet sichere Defaults
- Tests verifizieren Cookie-Sicherheitsflags
- Lokale Entwicklung bleibt funktional (über `.env` Override)
2026-02-11 23:19:31 +01:00

84 lines
1.5 KiB
Plaintext

APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_URL=http://localhost
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=einundzwanzig_verein
DB_USERNAME=postgres
DB_PASSWORD=secret
DB_HOST_EINUNDZANZIG=127.0.0.1
DB_PORT_EINUNDZANZIG=5432
DB_DATABASE_EINUNDZANZIG=einundzwanzig_app
DB_USERNAME_EINUNDZANZIG=postgres
DB_PASSWORD_EINUNDZANZIG=secret
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_SECURE_COOKIE=true
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=reverb
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
REVERB_APP_ID=521000
REVERB_APP_KEY=laravel-reverb-key
REVERB_APP_SECRET=laravel-reverb-secret
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"