144 lines
4.9 KiB
Markdown
144 lines
4.9 KiB
Markdown
|
|
# PR1 — Fix P0 Critiques (Sécurité/Ops)
|
||
|
|
|
||
|
|
## Résumé
|
||
|
|
|
||
|
|
Cette PR corrige 3 problèmes critiques (P0) identifiés dans l'audit exhaustif :
|
||
|
|
- **MOD-P0-003**: Dockerfile.production path incorrect
|
||
|
|
- **MOD-P0-001**: CORS fail-fast en production si origines vides
|
||
|
|
- **MOD-P0-002**: Redaction secrets dans logs même en DEBUG
|
||
|
|
|
||
|
|
## Items Corrigés
|
||
|
|
|
||
|
|
### MOD-P0-003: Dockerfile.production Path
|
||
|
|
**Fichier**: `Dockerfile.production:30`
|
||
|
|
**Problème**: Chemin `./main.go` n'existe pas, devrait être `./cmd/api/main.go`
|
||
|
|
**Fix**: Corrigé le chemin vers `./cmd/api/main.go`
|
||
|
|
**Validation**:
|
||
|
|
```bash
|
||
|
|
docker build -f Dockerfile.production -t veza-backend-api:test .
|
||
|
|
# ✅ Build réussit
|
||
|
|
```
|
||
|
|
|
||
|
|
### MOD-P0-001: CORS Fail-Fast en Production
|
||
|
|
**Fichier**: `internal/config/config.go:639-648`
|
||
|
|
**Problème**: Si `CORS_ALLOWED_ORIGINS` vide en production, service démarre mais rejette toutes requêtes CORS (inaccessible)
|
||
|
|
**Fix**: Fail-fast au démarrage si `CORS_ALLOWED_ORIGINS` vide en production
|
||
|
|
**Validation**:
|
||
|
|
```bash
|
||
|
|
APP_ENV=production CORS_ALLOWED_ORIGINS="" go run ./cmd/api/main.go
|
||
|
|
# ✅ Erreur: "CORS_ALLOWED_ORIGINS is required in production environment..."
|
||
|
|
```
|
||
|
|
|
||
|
|
**Test mis à jour**: `TestLoadConfig_ProdMissingCritical` vérifie maintenant que l'erreur est retournée
|
||
|
|
|
||
|
|
### MOD-P0-002: Redaction Secrets dans Logs
|
||
|
|
**Fichiers**:
|
||
|
|
- `internal/config/secrets.go:63-77` (ajout secrets manquants)
|
||
|
|
- `internal/config/config.go:740-757` (masquage dans logConfigInitialized)
|
||
|
|
|
||
|
|
**Problème**: Secrets peuvent être exposés dans logs même en DEBUG
|
||
|
|
**Fix**:
|
||
|
|
1. Ajout de `DATABASE_URL`, `REDIS_URL`, `RABBITMQ_URL`, `CHAT_JWT_SECRET`, `SENTRY_DSN` dans liste des secrets
|
||
|
|
2. Masquage de tous les secrets dans `logConfigInitialized()` même en DEBUG
|
||
|
|
**Validation**:
|
||
|
|
```bash
|
||
|
|
# Vérifier que secrets sont masqués dans logs
|
||
|
|
APP_ENV=development LOG_LEVEL=DEBUG JWT_SECRET=my-secret-key go run ./cmd/api/main.go 2>&1 | grep -i "jwt_secret\|database_url"
|
||
|
|
# ✅ Secrets masqués (format: "xxxx****xxxx")
|
||
|
|
```
|
||
|
|
|
||
|
|
## Fichiers Modifiés
|
||
|
|
|
||
|
|
1. `Dockerfile.production` (ligne 30, 53)
|
||
|
|
- Fix path build: `./main.go` → `./cmd/api/main.go`
|
||
|
|
- Fix syntaxe COPY migrations (gestion dossier optionnel)
|
||
|
|
|
||
|
|
2. `internal/config/config.go` (lignes 639-648, 740-757)
|
||
|
|
- Fail-fast CORS en production si vide
|
||
|
|
- Masquage secrets supplémentaires dans logs
|
||
|
|
|
||
|
|
3. `internal/config/secrets.go` (lignes 63-77)
|
||
|
|
- Ajout secrets manquants: `DATABASE_URL`, `REDIS_URL`, `RABBITMQ_URL`, `CHAT_JWT_SECRET`, `SENTRY_DSN`
|
||
|
|
|
||
|
|
4. `internal/config/config_test.go` (lignes 457-462)
|
||
|
|
- Mise à jour test `TestLoadConfig_ProdMissingCritical` pour vérifier fail-fast
|
||
|
|
|
||
|
|
## Commandes de Validation
|
||
|
|
|
||
|
|
### Build
|
||
|
|
```bash
|
||
|
|
# Compilation
|
||
|
|
go build ./cmd/api/main.go
|
||
|
|
# ✅ Succès
|
||
|
|
|
||
|
|
# Docker build
|
||
|
|
docker build -f Dockerfile.production -t veza-backend-api:test .
|
||
|
|
# ✅ Succès
|
||
|
|
```
|
||
|
|
|
||
|
|
### Tests
|
||
|
|
```bash
|
||
|
|
# Tests config
|
||
|
|
go test ./internal/config -v -count=1
|
||
|
|
# ✅ Tous passent (y compris TestLoadConfig_ProdMissingCritical)
|
||
|
|
|
||
|
|
# Tests globaux (unitaires)
|
||
|
|
go test ./... -count=1 -short
|
||
|
|
# ✅ Tests unitaires passent (tests d'intégration échouent - P1, PR2)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Validation CORS Fail-Fast
|
||
|
|
```bash
|
||
|
|
# Test fail-fast CORS en production
|
||
|
|
APP_ENV=production \
|
||
|
|
JWT_SECRET=test-jwt-secret-key-minimum-32-characters-long \
|
||
|
|
DATABASE_URL=postgresql://test:test@localhost:5432/test_db \
|
||
|
|
REDIS_URL=redis://localhost:6379 \
|
||
|
|
CORS_ALLOWED_ORIGINS="" \
|
||
|
|
go run ./cmd/api/main.go
|
||
|
|
# ✅ Erreur: "CORS_ALLOWED_ORIGINS is required in production environment..."
|
||
|
|
```
|
||
|
|
|
||
|
|
### Validation Masquage Secrets
|
||
|
|
```bash
|
||
|
|
# Test masquage secrets dans logs
|
||
|
|
APP_ENV=development \
|
||
|
|
LOG_LEVEL=DEBUG \
|
||
|
|
JWT_SECRET=my-super-secret-jwt-key-32-chars \
|
||
|
|
DATABASE_URL=postgresql://user:password@localhost:5432/db \
|
||
|
|
go run ./cmd/api/main.go 2>&1 | grep -E "jwt_secret|database_url"
|
||
|
|
# ✅ Output: "jwt_secret":"my-s****-32-chars" (masqué)
|
||
|
|
# ✅ Output: "database_url":"post****db" (masqué)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Risques / Limitations
|
||
|
|
|
||
|
|
1. **CORS Fail-Fast**: Service ne démarre pas en production si `CORS_ALLOWED_ORIGINS` non configuré
|
||
|
|
- **Impact**: Déploiement échoue si config manquante (comportement attendu pour sécurité)
|
||
|
|
- **Mitigation**: Documentation requiert `CORS_ALLOWED_ORIGINS` en production
|
||
|
|
|
||
|
|
2. **Dockerfile Migrations**: Si dossier `migrations/` n'existe pas, build réussit mais migrations non copiées
|
||
|
|
- **Impact**: Aucun (migrations optionnelles, peuvent être montées via volume)
|
||
|
|
- **Mitigation**: Aucune nécessaire
|
||
|
|
|
||
|
|
3. **Masquage Secrets**: Secrets partiellement visibles (4 premiers + 4 derniers caractères)
|
||
|
|
- **Impact**: Faible (suffisant pour debugging sans exposer secret complet)
|
||
|
|
- **Mitigation**: Aucune nécessaire (comportement attendu)
|
||
|
|
|
||
|
|
## Tests Ajoutés/Modifiés
|
||
|
|
|
||
|
|
- ✅ `TestLoadConfig_ProdMissingCritical`: Mis à jour pour vérifier fail-fast CORS
|
||
|
|
|
||
|
|
## Prochaines Étapes
|
||
|
|
|
||
|
|
- ✅ PR1 complétée
|
||
|
|
- ⏭️ PR2: Fix tests d'intégration (MOD-P1-001)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Statut**: ✅ **READY FOR REVIEW**
|
||
|
|
|
||
|
|
**Effort**: ~3h (comme estimé dans audit)
|
||
|
|
|
||
|
|
**Breaking Changes**: Aucun (sauf fail-fast CORS en production, qui est une amélioration sécurité)
|