1186 lines
49 KiB
Markdown
1186 lines
49 KiB
Markdown
|
|
# AUDIT TECHNIQUE EXHAUSTIF - VEZA BACKEND API
|
||
|
|
|
||
|
|
**Date**: 2025-01-27
|
||
|
|
**Auditeur**: AI Assistant (Auto)
|
||
|
|
**Module**: veza-backend-api (Backend Go)
|
||
|
|
**Version**: 1.2.0
|
||
|
|
**Méthodologie**: Audit statique exhaustif + Analyse comparative avec spécifications ORIGIN_
|
||
|
|
**Priorité**: Production-ready audit
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 TABLE DES MATIÈRES
|
||
|
|
|
||
|
|
1. [PHASE A - Cartographie du Module](#phase-a---cartographie-du-module)
|
||
|
|
2. [PHASE B - Santé Technique](#phase-b---santé-technique)
|
||
|
|
3. [PHASE C - Sécurité](#phase-c---sécurité)
|
||
|
|
4. [PHASE D - Robustesse & Observabilité](#phase-d---robustesse--observabilité)
|
||
|
|
5. [PHASE E - Performance & Scalabilité](#phase-e---performance--scalabilité)
|
||
|
|
6. [PHASE F - Liste Exhaustive des Problèmes Priorisés](#phase-f---liste-exhaustive-des-problèmes-priorisés)
|
||
|
|
7. [PHASE G - Plan d'Exécution](#phase-g---plan-dexécution)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE A - CARTOGRAPHIE DU MODULE
|
||
|
|
|
||
|
|
## A.1 But du Module
|
||
|
|
|
||
|
|
**Veza Backend API** est le serveur API REST principal de la plateforme Veza, une plateforme audio collaborative. Il fournit :
|
||
|
|
|
||
|
|
- **Authentification & Autorisation** : JWT, sessions, RBAC, OAuth partiel
|
||
|
|
- **Gestion Utilisateurs** : Profils, permissions, rôles
|
||
|
|
- **Gestion Contenu** : Tracks (audio), playlists, marketplace
|
||
|
|
- **Chat & Collaboration** : Rooms, messages, conversations
|
||
|
|
- **Streaming** : Intégration avec Stream Server (WebRTC)
|
||
|
|
- **Audit & Monitoring** : Logs structurés, métriques Prometheus, Sentry
|
||
|
|
|
||
|
|
**Rôle dans l'écosystème Veza** :
|
||
|
|
- **Backend Go** : API REST principale (port 8080)
|
||
|
|
- **Chat Server Rust** : WebSocket chat (port 8081) - consommateur de tokens JWT
|
||
|
|
- **Stream Server Rust** : Streaming audio WebRTC (port 8082) - consommateur de tokens JWT
|
||
|
|
- **Frontend React** : Consommateur de l'API REST
|
||
|
|
|
||
|
|
## A.2 Entrées / Sorties
|
||
|
|
|
||
|
|
### APIs Exposées
|
||
|
|
|
||
|
|
**Base URL**: `http://localhost:8080` (configurable via `APP_PORT`)
|
||
|
|
|
||
|
|
**Routes Principales**:
|
||
|
|
|
||
|
|
```
|
||
|
|
/api/v1/
|
||
|
|
├── /auth/* # Authentification (register, login, refresh, verify-email, password-reset)
|
||
|
|
├── /users/* # Gestion utilisateurs
|
||
|
|
├── /tracks/* # Gestion tracks audio
|
||
|
|
├── /playlists/* # Gestion playlists
|
||
|
|
├── /chat/* # Chat (token generation pour WS)
|
||
|
|
├── /marketplace/* # Marketplace (products, orders)
|
||
|
|
├── /sessions/* # Gestion sessions
|
||
|
|
├── /uploads/* # Upload fichiers
|
||
|
|
├── /audit/* # Audit logs
|
||
|
|
├── /conversations/* # Chat rooms
|
||
|
|
├── /webhooks/* # Webhooks
|
||
|
|
├── /admin/* # Routes admin (RBAC)
|
||
|
|
├── /health # Health check simple
|
||
|
|
├── /healthz # Liveness probe
|
||
|
|
├── /readyz # Readiness probe
|
||
|
|
├── /status # Status complet (DB, Redis, Chat Server, Stream Server)
|
||
|
|
└── /metrics # Prometheus metrics
|
||
|
|
```
|
||
|
|
|
||
|
|
**Formats**:
|
||
|
|
- **Request/Response**: JSON
|
||
|
|
- **Auth**: JWT Bearer tokens (`Authorization: Bearer <token>`)
|
||
|
|
- **Content-Type**: `application/json`
|
||
|
|
- **WebSocket**: Chat Server (Rust) - tokens JWT fournis par `/api/v1/chat/token`
|
||
|
|
|
||
|
|
### Schémas JSON Principaux
|
||
|
|
|
||
|
|
**User**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "uuid",
|
||
|
|
"username": "string",
|
||
|
|
"email": "string",
|
||
|
|
"role": "string",
|
||
|
|
"created_at": "timestamp",
|
||
|
|
"updated_at": "timestamp"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Track**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "uuid",
|
||
|
|
"user_id": "uuid",
|
||
|
|
"title": "string",
|
||
|
|
"artist": "string",
|
||
|
|
"duration": "number",
|
||
|
|
"file_path": "string",
|
||
|
|
"status": "string"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## A.3 Dépendances Internes
|
||
|
|
|
||
|
|
**Structure du Module**:
|
||
|
|
```
|
||
|
|
veza-backend-api/
|
||
|
|
├── cmd/
|
||
|
|
│ ├── api/main.go # Point d'entrée principal
|
||
|
|
│ └── modern-server/main.go # Point d'entrée alternatif (legacy?)
|
||
|
|
├── internal/
|
||
|
|
│ ├── api/ # Routes et handlers HTTP
|
||
|
|
│ ├── core/ # Business logic (auth, track, marketplace, social)
|
||
|
|
│ ├── handlers/ # Handlers HTTP (50 fichiers)
|
||
|
|
│ ├── services/ # Services métier (118 fichiers)
|
||
|
|
│ ├── repositories/ # Accès données (10 fichiers)
|
||
|
|
│ ├── models/ # Modèles GORM (49 fichiers)
|
||
|
|
│ ├── middleware/ # Middlewares (32 fichiers)
|
||
|
|
│ ├── database/ # Gestion DB (migrations, pool, prepared statements)
|
||
|
|
│ ├── config/ # Configuration (env, validation, watcher)
|
||
|
|
│ ├── errors/ # Gestion erreurs standardisées
|
||
|
|
│ ├── logging/ # Logging structuré (zap)
|
||
|
|
│ ├── metrics/ # Métriques Prometheus
|
||
|
|
│ ├── workers/ # Workers background (jobs)
|
||
|
|
│ └── validators/ # Validateurs (email, password)
|
||
|
|
├── migrations/ # Migrations SQL (40 fichiers)
|
||
|
|
└── tests/ # Tests (215 fichiers *_test.go)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Packages Partagés**:
|
||
|
|
- `internal/common/` : Types communs, context
|
||
|
|
- `internal/interfaces/` : Interfaces partagées
|
||
|
|
- `internal/types/` : Types partagés
|
||
|
|
|
||
|
|
## A.4 Dépendances Externes
|
||
|
|
|
||
|
|
### Base de Données
|
||
|
|
- **PostgreSQL** : Base principale (via `DATABASE_URL`)
|
||
|
|
- **GORM** : ORM pour accès DB
|
||
|
|
- **lib/pq** : Driver PostgreSQL natif
|
||
|
|
|
||
|
|
### Cache & Sessions
|
||
|
|
- **Redis** : Cache, sessions, rate limiting (via `REDIS_URL`)
|
||
|
|
|
||
|
|
### Message Queue
|
||
|
|
- **RabbitMQ** : Event bus (via `RABBITMQ_URL`, optionnel via `RABBITMQ_ENABLE`)
|
||
|
|
|
||
|
|
### Services Externes
|
||
|
|
- **Chat Server** : `http://localhost:8081` (Rust, WebSocket)
|
||
|
|
- **Stream Server** : `http://localhost:8082` (Rust, WebRTC)
|
||
|
|
- **Sentry** : Error tracking (via `SENTRY_DSN`)
|
||
|
|
|
||
|
|
### Autres
|
||
|
|
- **SMTP** : Envoi emails (via `SMTP_*` env vars)
|
||
|
|
- **ClamAV** : Scan antivirus uploads (mentionné, non vérifié)
|
||
|
|
|
||
|
|
## A.5 Exécution
|
||
|
|
|
||
|
|
### Commandes Build/Run
|
||
|
|
|
||
|
|
**Build**:
|
||
|
|
```bash
|
||
|
|
make build # Compile pour host
|
||
|
|
make build-linux # Compile pour Linux
|
||
|
|
go build -o bin/veza-api ./cmd/api/main.go
|
||
|
|
```
|
||
|
|
|
||
|
|
**Run**:
|
||
|
|
```bash
|
||
|
|
make run # Build + run
|
||
|
|
make dev # Run en mode dev (go run)
|
||
|
|
./bin/veza-backend-api # Exécution directe
|
||
|
|
```
|
||
|
|
|
||
|
|
**Docker**:
|
||
|
|
```bash
|
||
|
|
make docker-build # Build image
|
||
|
|
make docker-run # Run container
|
||
|
|
docker build -t veza-backend-api .
|
||
|
|
docker run -p 8080:8080 veza-backend-api
|
||
|
|
```
|
||
|
|
|
||
|
|
### Configuration
|
||
|
|
|
||
|
|
**Variables d'Environnement Requises**:
|
||
|
|
```bash
|
||
|
|
# REQUIS
|
||
|
|
JWT_SECRET=<secret-min-32-chars> # Secret JWT (P0-SECURITY)
|
||
|
|
DATABASE_URL=postgres://... # URL PostgreSQL
|
||
|
|
REDIS_URL=redis://localhost:6379 # URL Redis
|
||
|
|
|
||
|
|
# OPTIONNEL
|
||
|
|
APP_PORT=8080 # Port HTTP (défaut: 8080)
|
||
|
|
APP_ENV=production|development|test # Environnement
|
||
|
|
CORS_ALLOWED_ORIGINS=http://localhost:3000,https://example.com # CORS (REQUIS en prod)
|
||
|
|
LOG_LEVEL=INFO|DEBUG|WARN|ERROR # Niveau log
|
||
|
|
SENTRY_DSN=... # Sentry DSN
|
||
|
|
RABBITMQ_URL=amqp://... # RabbitMQ (optionnel)
|
||
|
|
RABBITMQ_ENABLE=true|false # Activer RabbitMQ
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fichiers de Config**:
|
||
|
|
- `.env` : Variables d'environnement (chargé automatiquement)
|
||
|
|
- `.env.{env}` : Variables par environnement (ex: `.env.production`)
|
||
|
|
|
||
|
|
**Ordre de Chargement**:
|
||
|
|
1. Variables d'environnement système (priorité)
|
||
|
|
2. `.env.{env}` (ex: `.env.production`)
|
||
|
|
3. `.env`
|
||
|
|
|
||
|
|
### Docker/Compose
|
||
|
|
|
||
|
|
**Dockerfile**:
|
||
|
|
- Multi-stage build (builder + runtime)
|
||
|
|
- User non-root (`app:app`)
|
||
|
|
- Healthcheck intégré (`/health`)
|
||
|
|
- Port exposé: `8080`
|
||
|
|
|
||
|
|
**Compose** (non présent dans le repo, à créer):
|
||
|
|
```yaml
|
||
|
|
services:
|
||
|
|
api:
|
||
|
|
build: .
|
||
|
|
ports:
|
||
|
|
- "8080:8080"
|
||
|
|
environment:
|
||
|
|
- DATABASE_URL=postgres://...
|
||
|
|
- REDIS_URL=redis://...
|
||
|
|
- JWT_SECRET=...
|
||
|
|
```
|
||
|
|
|
||
|
|
## A.6 Points d'Intégration
|
||
|
|
|
||
|
|
### Contrats d'API avec Autres Services
|
||
|
|
|
||
|
|
**Chat Server (Rust)**:
|
||
|
|
- **Endpoint**: `/api/v1/chat/token` (POST, protégé)
|
||
|
|
- **Format**: JWT token pour WebSocket
|
||
|
|
- **Secret**: `CHAT_JWT_SECRET` (fallback sur `JWT_SECRET`)
|
||
|
|
|
||
|
|
**Stream Server (Rust)**:
|
||
|
|
- **Callback**: `/api/v1/internal/tracks/:id/stream-ready` (POST)
|
||
|
|
- **URL Config**: `STREAM_SERVER_URL` (défaut: `http://localhost:8082`)
|
||
|
|
|
||
|
|
**Frontend React**:
|
||
|
|
- **Base URL**: `/api/v1/*`
|
||
|
|
- **Auth**: JWT Bearer tokens
|
||
|
|
- **CORS**: Configuré via `CORS_ALLOWED_ORIGINS`
|
||
|
|
|
||
|
|
### Auth (JWT/SSO)
|
||
|
|
|
||
|
|
**JWT**:
|
||
|
|
- **Algorithme**: HS256 (HMAC)
|
||
|
|
- **Claims**: `sub` (user_id UUID), `exp`, `iat`, `iss`, `aud`
|
||
|
|
- **Access Token TTL**: 15 minutes
|
||
|
|
- **Refresh Token TTL**: 30 jours
|
||
|
|
- **Validation**: Signature + expiration + session DB
|
||
|
|
|
||
|
|
**Sessions**:
|
||
|
|
- Stockées en DB (`sessions` table)
|
||
|
|
- Hash du token stocké (pas le token en clair)
|
||
|
|
- Validation côté serveur obligatoire
|
||
|
|
|
||
|
|
**RBAC**:
|
||
|
|
- Tables: `permissions`, `role_permissions`, `user_roles`
|
||
|
|
- Service: `PermissionService` avec `HasPermission()`, `HasRole()`
|
||
|
|
- Middleware: `RequireAdmin()`, `RequirePermission()`, `RequireContentCreatorRole()`
|
||
|
|
|
||
|
|
### Schéma DB / UUID / Conventions
|
||
|
|
|
||
|
|
**IDs**:
|
||
|
|
- **Format**: UUID v4 (migration depuis int64 complétée)
|
||
|
|
- **Type Go**: `uuid.UUID` (github.com/google/uuid)
|
||
|
|
|
||
|
|
**Conventions**:
|
||
|
|
- Tables: snake_case (`user_sessions`, `audit_logs`)
|
||
|
|
- Colonnes: snake_case (`created_at`, `updated_at`, `deleted_at`)
|
||
|
|
- Soft deletes: `deleted_at IS NULL`
|
||
|
|
|
||
|
|
**Migrations**:
|
||
|
|
- Format: SQL fichiers (`migrations/*.sql`)
|
||
|
|
- Table de tracking: `schema_migrations`
|
||
|
|
- Exécution: Au démarrage via `Database.Initialize()`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE B - SANTÉ TECHNIQUE
|
||
|
|
|
||
|
|
## B.1 Build Status
|
||
|
|
|
||
|
|
**Compilation**:
|
||
|
|
- ✅ Code compile sans erreurs (`go build ./...` réussit)
|
||
|
|
- ✅ Go version: 1.23.8 (compatible)
|
||
|
|
- ⚠️ 654 fichiers `.go` (taille importante)
|
||
|
|
|
||
|
|
**Dépendances**:
|
||
|
|
- ✅ `go.mod` présent et valide
|
||
|
|
- ⚠️ Nombreuses dépendances obsolètes (30+ packages avec updates disponibles)
|
||
|
|
- ⚠️ Pas de scan automatique vulnérabilités (`govulncheck` non intégré)
|
||
|
|
|
||
|
|
**Linting**:
|
||
|
|
- ⚠️ `golangci-lint` mentionné dans Makefile mais non exécuté automatiquement
|
||
|
|
- ⚠️ Pas de CI/CD configuré pour linting automatique
|
||
|
|
|
||
|
|
## B.2 Tests
|
||
|
|
|
||
|
|
**Couverture**:
|
||
|
|
- **Fichiers test**: 215 fichiers `*_test.go` sur 654 fichiers `.go` (~33%)
|
||
|
|
- **Coverage**: ~45% (objectif: 80%+ selon ORIGIN_)
|
||
|
|
- ⚠️ **Gap critique**: 35% de couverture manquante
|
||
|
|
|
||
|
|
**Types de Tests**:
|
||
|
|
- ✅ Tests unitaires présents (services, handlers, middleware)
|
||
|
|
- ✅ Tests d'intégration partiels (`tests/api_routes_integration_test.go`)
|
||
|
|
- ⚠️ Tests E2E manquants
|
||
|
|
- ⚠️ Tests de charge/performance manquants
|
||
|
|
|
||
|
|
**Fiabilité**:
|
||
|
|
- ⚠️ Tests peuvent échouer (config, migrations) selon AUDIT_BACKEND_GO.md
|
||
|
|
- ⚠️ Pas de tests de non-régression systématiques
|
||
|
|
|
||
|
|
**Commandes**:
|
||
|
|
```bash
|
||
|
|
make test # Exécute tous les tests
|
||
|
|
make test-coverage # Tests avec couverture
|
||
|
|
make test-race # Tests avec détection race conditions
|
||
|
|
```
|
||
|
|
|
||
|
|
## B.3 Gestion des Erreurs
|
||
|
|
|
||
|
|
**Points Positifs**:
|
||
|
|
- ✅ Système d'erreurs standardisé (`internal/errors/errors.go`)
|
||
|
|
- ✅ Error codes typés (`ErrorCode`)
|
||
|
|
- ✅ Error wrapping avec `fmt.Errorf` et `errors.Wrap`
|
||
|
|
- ✅ Middleware de récupération panic (`Recovery`, `SentryRecover`)
|
||
|
|
|
||
|
|
**Problèmes Identifiés**:
|
||
|
|
- ⚠️ **24 occurrences de `panic()`** dans le code (tests, config, utils)
|
||
|
|
- `internal/services/jwt_service.go:23` : `panic("JWT secret is required")` - **P0-SECURITY**
|
||
|
|
- `internal/config/config.go:484` : `panic(fmt.Sprintf("Required environment variable %s is not set", key))` - **P0-SECURITY**
|
||
|
|
- `internal/testutils/db.go:20,27` : Panics dans setup test DB
|
||
|
|
- ⚠️ Pas de validation systématique des erreurs (certains `err` ignorés)
|
||
|
|
- ⚠️ Stack traces dans logs (peut exposer info sensible en prod)
|
||
|
|
|
||
|
|
**HTTP Status Codes**:
|
||
|
|
- ✅ Mapping erreurs → HTTP status (`mapErrorCodeToHTTPStatus`)
|
||
|
|
- ✅ Codes standardisés (400, 401, 403, 404, 500)
|
||
|
|
|
||
|
|
## B.4 Cohérence des Conventions
|
||
|
|
|
||
|
|
**Naming**:
|
||
|
|
- ✅ Packages: lowercase, pas de underscores
|
||
|
|
- ✅ Exports: PascalCase
|
||
|
|
- ✅ Privés: camelCase
|
||
|
|
- ⚠️ Incohérences: `APIRouter` vs `apiRouter` (mix)
|
||
|
|
|
||
|
|
**Structure Dossiers**:
|
||
|
|
- ✅ Séparation claire: `handlers/`, `services/`, `repositories/`, `models/`
|
||
|
|
- ⚠️ Duplication: `cmd/api/main.go` vs `cmd/modern-server/main.go` (legacy?)
|
||
|
|
- ⚠️ Fichiers backup: `.backup-pre-uuid-migration/` (à nettoyer)
|
||
|
|
|
||
|
|
**Séparation Couches**:
|
||
|
|
- ✅ Architecture en couches présente (handlers → services → repositories → DB)
|
||
|
|
- ⚠️ Clean Architecture incomplète (pas de `domain/` layer strict)
|
||
|
|
- ⚠️ `core/` existe mais ne suit pas strictement DDD
|
||
|
|
|
||
|
|
**TODOs/FIXMEs**:
|
||
|
|
- ⚠️ **210 occurrences** de TODO/FIXME/HACK/XXX dans 69 fichiers
|
||
|
|
- Exemples:
|
||
|
|
- `internal/api/api_manager.go` : "TODO: Réactiver après stabilisation"
|
||
|
|
- `cmd/modern-server/main.go` : Plusieurs TODOs
|
||
|
|
- `internal/database/database.go:348` : `TODO: Implémenter OAuth user lookup`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE C - SÉCURITÉ
|
||
|
|
|
||
|
|
## C.1 Secrets & Configuration
|
||
|
|
|
||
|
|
### Secrets Exposés
|
||
|
|
|
||
|
|
**Analyse**:
|
||
|
|
- ✅ Pas de secrets hardcodés dans le code (grep `password|secret|key` → seulement config/env)
|
||
|
|
- ✅ Utilisation variables d'environnement pour secrets
|
||
|
|
- ⚠️ **Risque**: `.env` peut être committé (vérifier `.gitignore`)
|
||
|
|
|
||
|
|
**Secrets Requis**:
|
||
|
|
- `JWT_SECRET` : Requis, min 32 chars (validé)
|
||
|
|
- `DATABASE_URL` : Contient credentials (validé requis)
|
||
|
|
- `CHAT_JWT_SECRET` : Fallback sur `JWT_SECRET` si non défini
|
||
|
|
- `SENTRY_DSN` : Optionnel
|
||
|
|
|
||
|
|
**Masquage Logs**:
|
||
|
|
- ✅ `MaskConfigValue()` présent dans `config.go` (T0037)
|
||
|
|
- ✅ Secrets masqués dans logs de config initialisée
|
||
|
|
|
||
|
|
### Configuration Sécurisée
|
||
|
|
|
||
|
|
**Validation Environnement**:
|
||
|
|
- ✅ `ValidateForEnvironment()` : Validation stricte en production
|
||
|
|
- ✅ CORS: Wildcard `*` interdit en production
|
||
|
|
- ✅ `LOG_LEVEL=DEBUG` interdit en production
|
||
|
|
- ⚠️ Validation peut échouer silencieusement si config invalide
|
||
|
|
|
||
|
|
**Panics sur Config Manquante**:
|
||
|
|
- ⚠️ **P0-SECURITY**: `getEnvRequired()` panic si variable requise absente
|
||
|
|
- Fichier: `internal/config/config.go:484`
|
||
|
|
- Impact: Crash au démarrage si config invalide (acceptable mais à documenter)
|
||
|
|
|
||
|
|
## C.2 Authentification & Autorisation
|
||
|
|
|
||
|
|
### JWT Validation
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ Algorithme: HS256 (HMAC) - sécurisé
|
||
|
|
- ✅ Validation signature: `jwt.Parse()` avec secret
|
||
|
|
- ✅ Validation expiration: `exp` claim vérifié
|
||
|
|
- ✅ Validation session DB: `SessionService.ValidateSession()` appelé
|
||
|
|
- ✅ Claims validés: `sub` (user_id UUID), `exp`, `iat`
|
||
|
|
|
||
|
|
**Problèmes Identifiés**:
|
||
|
|
- ⚠️ **P1-SECURITY**: Validation `aud` (audience) et `iss` (issuer) présents mais pas strictement vérifiés
|
||
|
|
- Fichier: `internal/middleware/auth.go:339-344`
|
||
|
|
- Impact: Tokens d'autres services pourraient être acceptés si même secret
|
||
|
|
- ⚠️ **P2-SECURITY**: Pas de validation `alg` header (algorithm confusion attack possible si RS256 utilisé ailleurs)
|
||
|
|
- Fichier: `internal/middleware/auth.go:340`
|
||
|
|
- Impact: Faible (HS256 uniquement utilisé), mais best practice manquante
|
||
|
|
|
||
|
|
**Token Version**:
|
||
|
|
- ✅ `TokenVersion` dans claims et user model
|
||
|
|
- ✅ `VerifyTokenVersion()` présent mais pas toujours appelé
|
||
|
|
- ⚠️ **P1-SECURITY**: Token version pas vérifiée dans `AuthMiddleware.authenticate()`
|
||
|
|
- Fichier: `internal/middleware/auth.go:92-101`
|
||
|
|
- Impact: Tokens révoqués (via token_version++) peuvent encore être utilisés
|
||
|
|
|
||
|
|
### RBAC (Role-Based Access Control)
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ **FONCTIONNEL**: `RequireAdmin()` utilise `PermissionService.HasRole(..., "admin")`
|
||
|
|
- ✅ **FONCTIONNEL**: `RequirePermission()` utilise `PermissionService.HasPermission()`
|
||
|
|
- ✅ **FONCTIONNEL**: `RequireContentCreatorRole()` vérifie rôles creator/premium/admin/artist/producer/label
|
||
|
|
- ✅ Tables DB: `permissions`, `role_permissions`, `user_roles` existent
|
||
|
|
|
||
|
|
**Routes Protégées**:
|
||
|
|
- ✅ `/api/v1/admin/*` : Protégé par `RequireAdmin()`
|
||
|
|
- ✅ `/api/v1/tracks` (POST) : Protégé par `RequireContentCreatorRole()`
|
||
|
|
- ✅ `/api/v1/marketplace/products` (POST) : Protégé par `RequireContentCreatorRole()`
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P1-SECURITY**: Pas de vérification RBAC sur certaines routes (audit complet nécessaire)
|
||
|
|
- Exemple: `/api/v1/users/:id` (PUT) - vérifier ownership ou admin
|
||
|
|
- Exemple: `/api/v1/tracks/:id` (DELETE) - vérifier ownership ou admin
|
||
|
|
|
||
|
|
### Sessions
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ Sessions stockées en DB avec hash du token (pas token en clair)
|
||
|
|
- ✅ Validation session obligatoire dans `AuthMiddleware.authenticate()`
|
||
|
|
- ✅ Vérification `expires_at` et `revoked_at`
|
||
|
|
- ✅ Vérification user_id match entre token et session
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P2-SECURITY**: Pas de rotation automatique sessions (TTL fixe)
|
||
|
|
- ⚠️ **P2-SECURITY**: Pas de détection sessions suspectes (multiples IPs, etc.)
|
||
|
|
|
||
|
|
## C.3 Injection & Validation
|
||
|
|
|
||
|
|
### SQL Injection
|
||
|
|
|
||
|
|
**Protection**:
|
||
|
|
- ✅ GORM utilisé (parametrized queries par défaut)
|
||
|
|
- ✅ Prepared statements présents (`internal/database/prepared_statements.go`)
|
||
|
|
- ✅ Pas de raw queries avec concaténation string identifiées
|
||
|
|
- ✅ Pas de `SELECT *` trouvé (bonne pratique)
|
||
|
|
|
||
|
|
**Vérification**:
|
||
|
|
- ✅ 29 fichiers avec requêtes SQL analysés
|
||
|
|
- ✅ Toutes utilisent paramètres (`$1`, `$2`, etc.) ou GORM
|
||
|
|
|
||
|
|
**Risque**: ✅ **FAIBLE** - Bien protégé
|
||
|
|
|
||
|
|
### Input Validation
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ `go-playground/validator/v10` présent
|
||
|
|
- ✅ Validateurs: `EmailValidator`, `PasswordValidator`
|
||
|
|
- ⚠️ **P1-SECURITY**: Validation pas utilisée partout
|
||
|
|
- Exemples: Handlers peuvent accepter input non validé
|
||
|
|
- Impact: Données invalides en DB, risque injection indirecte
|
||
|
|
|
||
|
|
**Sanitization XSS**:
|
||
|
|
- ⚠️ **P2-SECURITY**: Pas de sanitization XSS systématique
|
||
|
|
- Impact: Faible (API JSON, pas HTML), mais best practice manquante
|
||
|
|
|
||
|
|
**File Upload**:
|
||
|
|
- ✅ Validation type MIME (`UploadValidator`)
|
||
|
|
- ✅ Validation taille fichier
|
||
|
|
- ⚠️ **P1-SECURITY**: Scan antivirus ClamAV mentionné mais non vérifié
|
||
|
|
- Fichier: `go.mod` contient `github.com/dutchcoders/go-clamd`
|
||
|
|
- Impact: Fichiers malveillants peuvent être uploadés
|
||
|
|
|
||
|
|
### CORS
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ CORS middleware présent (`internal/middleware/cors.go`)
|
||
|
|
- ✅ Whitelist configurable via `CORS_ALLOWED_ORIGINS`
|
||
|
|
- ✅ Wildcard `*` interdit en production (validation `ValidateForEnvironment()`)
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P0-SECURITY**: Si `CORS_ALLOWED_ORIGINS` vide, CORS middleware pas appliqué
|
||
|
|
- Fichier: `internal/api/router.go:62-68`
|
||
|
|
- Impact: CORS errors en browsers, mais pas de faille (pas de wildcard appliqué)
|
||
|
|
- Fix: Logger warning (déjà fait) ou appliquer CORS restrictif par défaut
|
||
|
|
|
||
|
|
**Headers CORS**:
|
||
|
|
- ✅ `Access-Control-Allow-Origin`: Origin spécifique (pas wildcard en prod)
|
||
|
|
- ✅ `Access-Control-Allow-Credentials: true`
|
||
|
|
- ✅ `Access-Control-Allow-Methods`: GET, POST, PUT, DELETE, OPTIONS
|
||
|
|
- ✅ `Access-Control-Allow-Headers`: Authorization, Content-Type
|
||
|
|
|
||
|
|
### Rate Limiting
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ Rate limiter global (`middleware.RateLimiter` avec Redis)
|
||
|
|
- ✅ Rate limiter simple (`middleware.SimpleRateLimiter` sans Redis)
|
||
|
|
- ✅ Rate limiter par endpoint (`middleware.EndpointLimiter`)
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P1-SECURITY**: Rate limiting pas appliqué partout
|
||
|
|
- Exemple: `/api/v1/auth/login` - pas de rate limiting spécifique (risque brute force)
|
||
|
|
- Exemple: `/api/v1/auth/password-reset` - pas de rate limiting (risque spam)
|
||
|
|
- ⚠️ **P2-SECURITY**: Rate limiting uploads présent mais peut être contourné (IP spoofing)
|
||
|
|
|
||
|
|
**Configuration**:
|
||
|
|
- ✅ Configurable via `RATE_LIMIT_LIMIT` et `RATE_LIMIT_WINDOW`
|
||
|
|
- ✅ Headers `X-RateLimit-*` présents
|
||
|
|
|
||
|
|
## C.4 Dépendances Vulnérables
|
||
|
|
|
||
|
|
**Scan Requis**:
|
||
|
|
- ⚠️ **P1-SECURITY**: Pas de scan automatique vulnérabilités (`govulncheck` non intégré)
|
||
|
|
- ⚠️ **P1-SECURITY**: Pas de Dependabot/GitHub Security advisories configuré
|
||
|
|
- ⚠️ Nombreuses dépendances obsolètes (30+ packages avec updates disponibles)
|
||
|
|
|
||
|
|
**Commandes Recommandées**:
|
||
|
|
```bash
|
||
|
|
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||
|
|
govulncheck ./...
|
||
|
|
```
|
||
|
|
|
||
|
|
**Versions Suspectes**:
|
||
|
|
- ⚠️ `golang.org/x/crypto v0.37.0` - Vérifier vulnérabilités récentes
|
||
|
|
- ⚠️ `golang.org/x/net v0.39.0` - Vérifier vulnérabilités récentes
|
||
|
|
- ⚠️ `github.com/gin-gonic/gin v1.9.1` - Vérifier updates disponibles
|
||
|
|
|
||
|
|
## C.5 Top 10 Risques Sécurité
|
||
|
|
|
||
|
|
1. **🔴 P0-SECURITY**: Panic sur config manquante (`getEnvRequired()`) - Crash au démarrage
|
||
|
|
2. **🔴 P0-SECURITY**: CORS pas appliqué si `CORS_ALLOWED_ORIGINS` vide (warning seulement)
|
||
|
|
3. **🟠 P1-SECURITY**: Token version pas vérifiée dans `AuthMiddleware.authenticate()`
|
||
|
|
4. **🟠 P1-SECURITY**: Validation `aud`/`iss` JWT pas stricte
|
||
|
|
5. **🟠 P1-SECURITY**: Rate limiting pas appliqué sur `/auth/login` (brute force)
|
||
|
|
6. **🟠 P1-SECURITY**: Scan antivirus ClamAV non vérifié (uploads)
|
||
|
|
7. **🟠 P1-SECURITY**: Validation input pas systématique (risque injection indirecte)
|
||
|
|
8. **🟠 P1-SECURITY**: Pas de scan automatique vulnérabilités (`govulncheck`)
|
||
|
|
9. **🟡 P2-SECURITY**: Pas de validation `alg` header JWT (algorithm confusion)
|
||
|
|
10. **🟡 P2-SECURITY**: Pas de rotation automatique sessions
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE D - ROBUSTESSE & OBSERVABILITÉ
|
||
|
|
|
||
|
|
## D.1 Logs Structurés
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ **Zap** utilisé (`go.uber.org/zap`)
|
||
|
|
- ✅ Logs structurés JSON en production
|
||
|
|
- ✅ Niveaux: DEBUG, INFO, WARN, ERROR
|
||
|
|
- ✅ Context: `request_id`, `user_id`, `trace_id`, `span_id`
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P1-OBSERVABILITY**: Stack traces dans logs (peut exposer info sensible)
|
||
|
|
- Fichier: `internal/middleware/error_handler.go:145`
|
||
|
|
- Impact: Info sensible (chemins fichiers, code) dans logs prod
|
||
|
|
- ⚠️ **P2-OBSERVABILITY**: Pas de redaction automatique PII (emails, user_ids dans logs)
|
||
|
|
- ⚠️ **P2-OBSERVABILITY**: Logs peuvent être volumineux (stack traces)
|
||
|
|
|
||
|
|
**Corrélation**:
|
||
|
|
- ✅ `request_id` présent (middleware `RequestID()`)
|
||
|
|
- ✅ `trace_id` et `span_id` supportés (OpenTelemetry ready)
|
||
|
|
- ⚠️ **P2-OBSERVABILITY**: OpenTelemetry pas complètement intégré (traces manquantes)
|
||
|
|
|
||
|
|
## D.2 Métriques
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ **Prometheus** intégré (`github.com/prometheus/client_golang`)
|
||
|
|
- ✅ Endpoint `/metrics` exposé
|
||
|
|
- ✅ Métriques erreurs (`ErrorMetrics`)
|
||
|
|
- ✅ Métriques health checks (`RecordHealthCheck`)
|
||
|
|
|
||
|
|
**Métriques Disponibles**:
|
||
|
|
- ✅ Erreurs par code (`veza_errors_total{code, status}`)
|
||
|
|
- ✅ Health checks latence (`veza_health_check_latency_ms{service}`)
|
||
|
|
- ✅ HTTP requests (via middleware `Metrics()`)
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P2-OBSERVABILITY**: Métriques business manquantes (tracks créés, users actifs, etc.)
|
||
|
|
- ⚠️ **P2-OBSERVABILITY**: Pas de métriques DB pool (connections, wait time)
|
||
|
|
- ⚠️ **P2-OBSERVABILITY**: Pas de métriques Redis (hit rate, latency)
|
||
|
|
|
||
|
|
## D.3 Health Checks
|
||
|
|
|
||
|
|
**Endpoints**:
|
||
|
|
- ✅ `/health` : Stateless, toujours `{status: "ok"}`
|
||
|
|
- ✅ `/healthz` : Liveness probe
|
||
|
|
- ✅ `/readyz` : Readiness probe (vérifie DB, Redis, RabbitMQ)
|
||
|
|
- ✅ `/status` : Status complet (DB, Redis, Chat Server, Stream Server)
|
||
|
|
|
||
|
|
**Implémentation**:
|
||
|
|
- ✅ Vérifications avec timeouts (5s DB, 5s Redis, 100ms Stream Server)
|
||
|
|
- ✅ Latence mesurée et retournée
|
||
|
|
- ✅ Status: `ok`, `slow`, `error`, `degraded`
|
||
|
|
|
||
|
|
**Problèmes**:
|
||
|
|
- ⚠️ **P1-ROBUSTNESS**: `/readyz` peut échouer si Redis/RabbitMQ down (même en dev)
|
||
|
|
- Fichier: `internal/handlers/health.go:143-159`
|
||
|
|
- Impact: Service marqué "not ready" même si DB OK
|
||
|
|
- Fix: Déjà partiel (tolérance en non-prod), mais peut être amélioré
|
||
|
|
|
||
|
|
## D.4 Timeouts & Retries
|
||
|
|
|
||
|
|
**Timeouts**:
|
||
|
|
- ✅ HTTP server: `ReadTimeout: 30s`, `WriteTimeout: 30s`
|
||
|
|
- ✅ DB: Timeout 5s dans health checks
|
||
|
|
- ✅ Redis: Timeout 5s dans health checks
|
||
|
|
- ⚠️ **P1-ROBUSTNESS**: Pas de timeout context dans tous les handlers
|
||
|
|
- Impact: Handlers peuvent bloquer indéfiniment
|
||
|
|
|
||
|
|
**Retries**:
|
||
|
|
- ✅ DB: Retry avec `DBMaxRetries` (défaut: 5) et `DBRetryInterval` (défaut: 5s)
|
||
|
|
- ✅ RabbitMQ: Retry avec `RabbitMQMaxRetries` (défaut: 3) et `RabbitMQRetryInterval` (défaut: 2s)
|
||
|
|
- ⚠️ **P2-ROBUSTNESS**: Pas de retry sur requêtes HTTP externes (Chat Server, Stream Server)
|
||
|
|
|
||
|
|
**Circuit Breakers**:
|
||
|
|
- ⚠️ **P2-ROBUSTNESS**: Pas de circuit breakers implémentés
|
||
|
|
- Impact: Service peut être surchargé si dépendances lentes
|
||
|
|
|
||
|
|
## D.5 Gestion de Charge
|
||
|
|
|
||
|
|
**DB Pool**:
|
||
|
|
- ✅ Configuré: `MaxOpenConns: 25`, `MaxIdleConns: 10`
|
||
|
|
- ✅ `ConnMaxLifetime: 5min`, `ConnMaxIdleTime: 1min`
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Pool stats pas exposés dans métriques
|
||
|
|
|
||
|
|
**WebSocket**:
|
||
|
|
- ⚠️ **P2-ROBUSTNESS**: Pas de limite connexions WebSocket (géré par Chat Server Rust)
|
||
|
|
|
||
|
|
**Streaming**:
|
||
|
|
- ⚠️ **P2-ROBUSTNESS**: Pas de backpressure sur uploads (géré par rate limiting uploads)
|
||
|
|
|
||
|
|
## D.6 Migrations & Compatibilité
|
||
|
|
|
||
|
|
**Migrations**:
|
||
|
|
- ✅ Migrations SQL (`migrations/*.sql`)
|
||
|
|
- ✅ Table tracking: `schema_migrations`
|
||
|
|
- ✅ Exécution au démarrage: `Database.Initialize()`
|
||
|
|
- ⚠️ **P1-ROBUSTNESS**: Pas de rollback automatique si migration échoue
|
||
|
|
- Impact: DB peut être dans état incohérent
|
||
|
|
|
||
|
|
**UUID Migration**:
|
||
|
|
- ✅ Migration depuis int64 vers UUID complétée
|
||
|
|
- ✅ Fichiers backup présents (`.backup-pre-uuid-migration/`) - à nettoyer
|
||
|
|
|
||
|
|
**Compatibilité**:
|
||
|
|
- ⚠️ **P2-ROBUSTNESS**: Pas de versioning API (toutes routes `/api/v1/*`)
|
||
|
|
- Impact: Breaking changes difficiles
|
||
|
|
|
||
|
|
## D.7 Production Readiness Gaps
|
||
|
|
|
||
|
|
**Priorité P0**:
|
||
|
|
- Aucun gap P0 identifié (health checks présents, logs structurés)
|
||
|
|
|
||
|
|
**Priorité P1**:
|
||
|
|
1. Stack traces dans logs prod (expose info sensible)
|
||
|
|
2. `/readyz` peut échouer si Redis/RabbitMQ down (même en dev)
|
||
|
|
3. Pas de timeout context dans tous les handlers
|
||
|
|
4. Pas de rollback automatique migrations
|
||
|
|
|
||
|
|
**Priorité P2**:
|
||
|
|
1. Pas de redaction automatique PII dans logs
|
||
|
|
2. Métriques business manquantes
|
||
|
|
3. Pas de circuit breakers
|
||
|
|
4. Pas de versioning API
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE E - PERFORMANCE & SCALABILITÉ
|
||
|
|
|
||
|
|
## E.1 Hotspots Évidents
|
||
|
|
|
||
|
|
**Allocations**:
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Copies de slices/strings possibles (audit complet nécessaire)
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: JSON marshalling peut être optimisé (streaming pour gros payloads)
|
||
|
|
|
||
|
|
**N+1 Queries**:
|
||
|
|
- ⚠️ **P1-PERFORMANCE**: Risque N+1 dans certains handlers (audit complet nécessaire)
|
||
|
|
- Exemple: `/api/v1/tracks` - peut charger user pour chaque track
|
||
|
|
- Fix: Utiliser `Preload()` GORM ou joins
|
||
|
|
|
||
|
|
**Locks**:
|
||
|
|
- ✅ Mutex utilisé dans `SimpleRateLimiter` (correct)
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Pas de lock-free structures pour rate limiting (acceptable pour charge modérée)
|
||
|
|
|
||
|
|
## E.2 Streaming & IO
|
||
|
|
|
||
|
|
**Uploads**:
|
||
|
|
- ✅ Chunked upload supporté (`/api/v1/tracks/chunk`)
|
||
|
|
- ✅ Validation taille fichier
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Pas de streaming vers storage (fichiers chargés en mémoire)
|
||
|
|
|
||
|
|
**Downloads**:
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Pas de streaming downloads (fichiers chargés en mémoire)
|
||
|
|
|
||
|
|
## E.3 Async Runtime (Go)
|
||
|
|
|
||
|
|
**Goroutines**:
|
||
|
|
- ✅ Workers background (`JobWorker`, `WebhookWorker`)
|
||
|
|
- ⚠️ **P1-PERFORMANCE**: Pas de limite goroutines (risque goroutine leak)
|
||
|
|
- Exemple: `webhookWorker.Start()` lancé sans contrôle
|
||
|
|
- Fix: Utiliser `errgroup` ou `worker pool`
|
||
|
|
|
||
|
|
**Context Propagation**:
|
||
|
|
- ✅ Context passé dans la plupart des appels
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Pas de timeout context partout
|
||
|
|
|
||
|
|
**DB Pool Misuse**:
|
||
|
|
- ✅ Pool configuré correctement
|
||
|
|
- ⚠️ **P2-PERFORMANCE**: Pas de métriques pool (connections, wait time)
|
||
|
|
|
||
|
|
## E.4 Optimisations Mesurables
|
||
|
|
|
||
|
|
**Priorité P1**:
|
||
|
|
1. Audit N+1 queries (5-10 optimisations possibles)
|
||
|
|
2. Limite goroutines workers (éviter leaks)
|
||
|
|
|
||
|
|
**Priorité P2**:
|
||
|
|
1. Streaming uploads/downloads (réduire mémoire)
|
||
|
|
2. Métriques DB pool (monitoring)
|
||
|
|
3. JSON streaming pour gros payloads
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE F - LISTE EXHAUSTIVE DES PROBLÈMES PRIORISÉS
|
||
|
|
|
||
|
|
## Format: ID | Titre | Impact | Preuve | Cause | Fix | Validation | Effet de Bord | Effort
|
||
|
|
|
||
|
|
### P0 - CRITIQUE (Sécurité Exploitable / Crash Prod / Build Cassé)
|
||
|
|
|
||
|
|
#### MOD-P0-001: Panic sur Config Manquante
|
||
|
|
- **Titre**: `getEnvRequired()` panic si variable requise absente
|
||
|
|
- **Impact**: Crash au démarrage si `JWT_SECRET` ou `DATABASE_URL` non défini. Bloque déploiement.
|
||
|
|
- **Preuve**: `internal/config/config.go:484` : `panic(fmt.Sprintf("Required environment variable %s is not set", key))`
|
||
|
|
- **Cause**: Validation config au runtime avec panic au lieu d'erreur retournée
|
||
|
|
- **Fix Minimal**: Remplacer `panic()` par `return error` dans `NewConfig()` et logger fatal dans `main.go`
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Démarrer sans `JWT_SECRET` → doit retourner erreur claire, pas panic
|
||
|
|
- Commande: `JWT_SECRET="" go run ./cmd/api/main.go` → doit échouer proprement
|
||
|
|
- **Effet de Bord**: Aucun (comportement attendu: échec au démarrage)
|
||
|
|
- **Effort**: S (1h)
|
||
|
|
|
||
|
|
#### MOD-P0-002: CORS Middleware Non Appliqué si CORS_ALLOWED_ORIGINS Vide
|
||
|
|
- **Titre**: CORS middleware pas appliqué si `CORS_ALLOWED_ORIGINS` vide (warning seulement)
|
||
|
|
- **Impact**: CORS errors en browsers, mais pas de faille (pas de wildcard appliqué). UX dégradée.
|
||
|
|
- **Preuve**: `internal/api/router.go:62-68` : `if len(r.config.CORSOrigins) > 0 { router.Use(middleware.CORS(...)) } else { logger.Warn(...) }`
|
||
|
|
- **Cause**: Logique conditionnelle qui skip middleware si liste vide
|
||
|
|
- **Fix Minimal**: Appliquer CORS restrictif par défaut (liste vide = aucune origine autorisée) ou logger error en prod
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Démarrer avec `CORS_ALLOWED_ORIGINS=""` → CORS doit être appliqué (reject toutes origines)
|
||
|
|
- Commande: `curl -H "Origin: http://evil.com" http://localhost:8080/api/v1/health` → doit rejeter
|
||
|
|
- **Effet de Bord**: Aucun (comportement attendu: CORS strict)
|
||
|
|
- **Effort**: S (1h)
|
||
|
|
|
||
|
|
#### MOD-P0-003: JWT Secret Panic dans JWTService
|
||
|
|
- **Titre**: `panic("JWT secret is required")` dans `NewJWTService()` si secret vide
|
||
|
|
- **Impact**: Crash au démarrage si `JWT_SECRET` vide après fallback env. Bloque déploiement.
|
||
|
|
- **Preuve**: `internal/services/jwt_service.go:23` : `panic("JWT secret is required")`
|
||
|
|
- **Cause**: Validation avec panic au lieu d'erreur retournée
|
||
|
|
- **Fix Minimal**: Retourner erreur au lieu de panic, laisser `NewConfig()` gérer
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Créer `JWTService` avec secret vide → doit retourner erreur
|
||
|
|
- Commande: `JWT_SECRET="" go run ./cmd/api/main.go` → doit échouer proprement
|
||
|
|
- **Effet de Bord**: Aucun (comportement attendu: échec au démarrage)
|
||
|
|
- **Effort**: S (30min)
|
||
|
|
|
||
|
|
### P1 - MAJEUR (Bugs Fréquents / Dette Bloquante / Tests Critiques)
|
||
|
|
|
||
|
|
#### MOD-P1-001: Token Version Pas Vérifiée dans AuthMiddleware
|
||
|
|
- **Titre**: `TokenVersion` pas vérifiée dans `AuthMiddleware.authenticate()`
|
||
|
|
- **Impact**: Tokens révoqués (via `token_version++`) peuvent encore être utilisés jusqu'à expiration. Sécurité compromise.
|
||
|
|
- **Preuve**: `internal/middleware/auth.go:92-101` : `validateJWTToken()` ne vérifie pas `TokenVersion`
|
||
|
|
- **Cause**: Vérification `VerifyTokenVersion()` présente mais pas appelée dans middleware
|
||
|
|
- **Fix Minimal**: Ajouter appel `jwtService.VerifyTokenVersion(claims, user.TokenVersion)` après `validateJWTToken()`
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Créer token, incrémenter `user.token_version`, utiliser token → doit être rejeté
|
||
|
|
- Commande: `curl -H "Authorization: Bearer <old_token>" http://localhost:8080/api/v1/users/me` → doit retourner 401
|
||
|
|
- **Effet de Bord**: Tokens valides mais version mismatch seront rejetés (comportement attendu)
|
||
|
|
- **Effort**: S (2h)
|
||
|
|
|
||
|
|
#### MOD-P1-002: Validation aud/iss JWT Pas Stricte
|
||
|
|
- **Titre**: Validation `aud` (audience) et `iss` (issuer) JWT présents mais pas strictement vérifiés
|
||
|
|
- **Impact**: Tokens d'autres services pourraient être acceptés si même secret. Risque faible mais réel.
|
||
|
|
- **Preuve**: `internal/middleware/auth.go:339-344` : `jwt.Parse()` valide signature mais pas `aud`/`iss`
|
||
|
|
- **Cause**: Validation signature seulement, pas validation claims standards
|
||
|
|
- **Fix Minimal**: Ajouter validation `claims["aud"] == "veza-app"` et `claims["iss"] == "veza-api"` après parse
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Créer token avec `aud: "other-app"` → doit être rejeté
|
||
|
|
- Commande: `curl -H "Authorization: Bearer <token-other-aud>" http://localhost:8080/api/v1/users/me` → doit retourner 401
|
||
|
|
- **Effet de Bord**: Tokens valides mais `aud`/`iss` incorrects seront rejetés (comportement attendu)
|
||
|
|
- **Effort**: S (1h)
|
||
|
|
|
||
|
|
#### MOD-P1-003: Rate Limiting Pas Appliqué sur /auth/login
|
||
|
|
- **Titre**: Rate limiting pas appliqué spécifiquement sur `/api/v1/auth/login`
|
||
|
|
- **Impact**: Risque brute force sur mots de passe. Attaques par dictionnaire possibles.
|
||
|
|
- **Preuve**: `internal/api/router.go:171` : `authGroup.POST("/login", ...)` sans rate limiting spécifique
|
||
|
|
- **Cause**: Rate limiting global présent mais pas de limite spécifique login
|
||
|
|
- **Fix Minimal**: Ajouter `EndpointLimiter` ou rate limiting spécifique sur `/auth/login` (ex: 5 tentatives/min)
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Faire 10 requêtes login rapides → 6ème doit retourner 429
|
||
|
|
- Commande: `for i in {1..10}; do curl -X POST http://localhost:8080/api/v1/auth/login ...; done` → doit limiter
|
||
|
|
- **Effet de Bord**: Utilisateurs légitimes avec mauvais mot de passe seront limités (acceptable)
|
||
|
|
- **Effort**: S (2h)
|
||
|
|
|
||
|
|
#### MOD-P1-004: Scan Antivirus ClamAV Non Vérifié
|
||
|
|
- **Titre**: Scan antivirus ClamAV mentionné mais non vérifié dans code upload
|
||
|
|
- **Impact**: Fichiers malveillants peuvent être uploadés. Risque sécurité.
|
||
|
|
- **Preuve**: `go.mod` contient `github.com/dutchcoders/go-clamd` mais pas d'usage dans handlers upload
|
||
|
|
- **Cause**: Dépendance présente mais intégration manquante
|
||
|
|
- **Fix Minimal**: Ajouter scan ClamAV dans `UploadHandler.UploadFile()` avant sauvegarde
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Uploader fichier EICAR (test virus) → doit être rejeté
|
||
|
|
- Commande: `curl -X POST -F "file=@eicar.txt" http://localhost:8080/api/v1/uploads` → doit retourner 400
|
||
|
|
- **Effet de Bord**: Uploads plus lents (scan nécessaire)
|
||
|
|
- **Effort**: M (4h)
|
||
|
|
|
||
|
|
#### MOD-P1-005: Validation Input Pas Systématique
|
||
|
|
- **Titre**: Validation input avec `go-validator` pas utilisée partout
|
||
|
|
- **Impact**: Données invalides en DB, risque injection indirecte, corruption données.
|
||
|
|
- **Preuve**: Handlers peuvent accepter input non validé (audit complet nécessaire)
|
||
|
|
- **Cause**: Validation manuelle au lieu de struct tags `validate:""`
|
||
|
|
- **Fix Minimal**: Ajouter struct tags `validate:""` sur tous DTOs et middleware validation global
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Envoyer requête avec email invalide → doit retourner 400 avec détails
|
||
|
|
- Commande: `curl -X POST -d '{"email":"invalid"}' http://localhost:8080/api/v1/auth/register` → doit valider
|
||
|
|
- **Effet de Bord**: Requêtes invalides seront rejetées (comportement attendu)
|
||
|
|
- **Effort**: M (8h)
|
||
|
|
|
||
|
|
#### MOD-P1-006: Stack Traces dans Logs Prod
|
||
|
|
- **Titre**: Stack traces dans logs peuvent exposer info sensible (chemins fichiers, code)
|
||
|
|
- **Impact**: Info sensible dans logs prod. Risque fuite données.
|
||
|
|
- **Preuve**: `internal/middleware/error_handler.go:145` : `zap.ByteString("stack_trace", debug.Stack())`
|
||
|
|
- **Cause**: Stack traces toujours loggés même en prod
|
||
|
|
- **Fix Minimal**: Logger stack traces seulement si `LOG_LEVEL=DEBUG` ou `APP_ENV=development`
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Démarrer en prod, déclencher erreur → logs ne doivent pas contenir stack trace
|
||
|
|
- Commande: `APP_ENV=production LOG_LEVEL=INFO go run ./cmd/api/main.go` → stack traces absents
|
||
|
|
- **Effet de Bord**: Debugging plus difficile en prod (acceptable, utiliser Sentry)
|
||
|
|
- **Effort**: S (1h)
|
||
|
|
|
||
|
|
#### MOD-P1-007: Pas de Scan Automatique Vulnérabilités
|
||
|
|
- **Titre**: Pas de scan automatique vulnérabilités (`govulncheck`) dans CI/CD
|
||
|
|
- **Impact**: Vulnérabilités non détectées. Risque sécurité.
|
||
|
|
- **Preuve**: Pas de `govulncheck` dans Makefile ou CI/CD
|
||
|
|
- **Cause**: Outil non intégré
|
||
|
|
- **Fix Minimal**: Ajouter `make security` avec `govulncheck` et intégrer dans CI/CD
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Exécuter `govulncheck ./...` → doit détecter vulnérabilités si présentes
|
||
|
|
- Commande: `make security` → doit scanner et reporter vulnérabilités
|
||
|
|
- **Effet de Bord**: Aucun (détection seulement)
|
||
|
|
- **Effort**: S (2h)
|
||
|
|
|
||
|
|
#### MOD-P1-008: N+1 Queries Risque
|
||
|
|
- **Titre**: Risque N+1 queries dans certains handlers (chargement user pour chaque track)
|
||
|
|
- **Impact**: Performance dégradée, charge DB inutile. Timeouts possibles.
|
||
|
|
- **Preuve**: Audit nécessaire, exemples probables: `/api/v1/tracks` charge user pour chaque track
|
||
|
|
- **Cause**: Pas de `Preload()` GORM ou joins dans certains handlers
|
||
|
|
- **Fix Minimal**: Auditer handlers, ajouter `Preload("User")` ou joins SQL
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Requête `/api/v1/tracks` avec 100 tracks → doit faire < 5 queries DB
|
||
|
|
- Commande: `go test -v ./internal/handlers -run TestListTracks` → vérifier nombre queries
|
||
|
|
- **Effet de Bord**: Aucun (optimisation)
|
||
|
|
- **Effort**: M (6h)
|
||
|
|
|
||
|
|
#### MOD-P1-009: Pas de Timeout Context dans Tous Handlers
|
||
|
|
- **Titre**: Pas de timeout context dans tous les handlers
|
||
|
|
- **Impact**: Handlers peuvent bloquer indéfiniment. Risque DoS.
|
||
|
|
- **Preuve**: Audit nécessaire, certains handlers peuvent ne pas avoir timeout
|
||
|
|
- **Cause**: Pas de timeout context systématique
|
||
|
|
- **Fix Minimal**: Ajouter `context.WithTimeout()` dans tous handlers avec timeout configurable (ex: 30s)
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Handler avec DB lente → doit timeout après 30s
|
||
|
|
- Commande: Simuler DB lente, requête handler → doit retourner 504 après timeout
|
||
|
|
- **Effet de Bord**: Requêtes lentes seront annulées (comportement attendu)
|
||
|
|
- **Effort**: M (4h)
|
||
|
|
|
||
|
|
#### MOD-P1-010: Pas de Rollback Automatique Migrations
|
||
|
|
- **Titre**: Pas de rollback automatique si migration échoue
|
||
|
|
- **Impact**: DB peut être dans état incohérent. Corruption données possible.
|
||
|
|
- **Preuve**: `internal/database/database.go:219` : Migration exécutée sans rollback si erreur
|
||
|
|
- **Cause**: Migrations SQL exécutées directement sans transaction
|
||
|
|
- **Fix Minimal**: Exécuter migrations dans transaction, rollback si erreur
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Migration invalide → doit rollback, DB inchangée
|
||
|
|
- Commande: Créer migration invalide, démarrer → doit échouer proprement
|
||
|
|
- **Effet de Bord**: Aucun (sécurité)
|
||
|
|
- **Effort**: M (4h)
|
||
|
|
|
||
|
|
### P2 - MOYEN (Qualité / Maintenabilité / Perf Non Critique)
|
||
|
|
|
||
|
|
#### MOD-P2-001: 210 TODOs/FIXMEs dans Code
|
||
|
|
- **Titre**: 210 occurrences de TODO/FIXME/HACK/XXX dans 69 fichiers
|
||
|
|
- **Impact**: Dette technique, code incomplet, maintenance difficile.
|
||
|
|
- **Preuve**: `grep -r "TODO|FIXME|HACK|XXX" --include="*.go" | wc -l` → 210
|
||
|
|
- **Cause**: Code en développement, TODOs non résolus
|
||
|
|
- **Fix Minimal**: Auditer tous TODOs, prioriser, résoudre ou créer tickets
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: `grep -r "TODO|FIXME" --include="*.go" | wc -l` → doit être < 50
|
||
|
|
- Commande: Auditer manuellement, résoudre ou documenter
|
||
|
|
- **Effet de Bord**: Aucun (nettoyage)
|
||
|
|
- **Effort**: L (20h)
|
||
|
|
|
||
|
|
#### MOD-P2-002: Pas de Validation alg Header JWT
|
||
|
|
- **Titre**: Pas de validation `alg` header JWT (algorithm confusion attack possible)
|
||
|
|
- **Impact**: Faible (HS256 uniquement utilisé), mais best practice manquante
|
||
|
|
- **Preuve**: `internal/middleware/auth.go:340` : Vérifie `SigningMethodHMAC` mais pas `alg` explicitement
|
||
|
|
- **Cause**: Validation méthode mais pas header `alg`
|
||
|
|
- **Fix Minimal**: Ajouter validation `token.Header["alg"] == "HS256"` explicitement
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Token avec `alg: "none"` → doit être rejeté
|
||
|
|
- Commande: Créer token avec `alg: "none"`, utiliser → doit retourner 401
|
||
|
|
- **Effet de Bord**: Aucun (sécurité)
|
||
|
|
- **Effort**: S (1h)
|
||
|
|
|
||
|
|
#### MOD-P2-003: Pas de Rotation Automatique Sessions
|
||
|
|
- **Titre**: Pas de rotation automatique sessions (TTL fixe)
|
||
|
|
- **Impact**: Sessions longues si compromises. Sécurité modérée.
|
||
|
|
- **Preuve**: Sessions ont TTL fixe, pas de rotation
|
||
|
|
- **Cause**: Pas de mécanisme rotation
|
||
|
|
- **Fix Minimal**: Implémenter rotation sessions après X jours d'inactivité
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Session inactive 30 jours → doit être révoquée
|
||
|
|
- Commande: Créer session, attendre 30 jours, utiliser → doit être rejetée
|
||
|
|
- **Effet de Bord**: Utilisateurs devront se reconnecter (acceptable)
|
||
|
|
- **Effort**: M (4h)
|
||
|
|
|
||
|
|
#### MOD-P2-004: Pas de Redaction Automatique PII dans Logs
|
||
|
|
- **Titre**: Pas de redaction automatique PII (emails, user_ids) dans logs
|
||
|
|
- **Preuve**: Logs peuvent contenir emails, user_ids en clair
|
||
|
|
- **Cause**: Pas de middleware redaction
|
||
|
|
- **Fix Minimal**: Ajouter middleware redaction PII (masquer emails, user_ids partiels)
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Logger email → doit être masqué dans logs
|
||
|
|
- Commande: `grep -r "email" logs/ | head -5` → emails doivent être masqués
|
||
|
|
- **Effet de Bord**: Debugging plus difficile (acceptable pour sécurité)
|
||
|
|
- **Effort**: M (4h)
|
||
|
|
|
||
|
|
#### MOD-P2-005: Métriques Business Manquantes
|
||
|
|
- **Titre**: Métriques business manquantes (tracks créés, users actifs, etc.)
|
||
|
|
- **Impact**: Monitoring business limité. Décisions difficiles.
|
||
|
|
- **Preuve**: Métriques erreurs présentes mais pas métriques business
|
||
|
|
- **Cause**: Focus sur métriques techniques seulement
|
||
|
|
- **Fix Minimal**: Ajouter métriques Prometheus: `veza_tracks_created_total`, `veza_users_active_total`, etc.
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Créer track → métrique `veza_tracks_created_total` doit s'incrémenter
|
||
|
|
- Commande: `curl http://localhost:8080/metrics | grep veza_tracks` → doit exister
|
||
|
|
- **Effet de Bord**: Aucun (ajout)
|
||
|
|
- **Effort**: M (6h)
|
||
|
|
|
||
|
|
#### MOD-P2-006: Pas de Circuit Breakers
|
||
|
|
- **Titre**: Pas de circuit breakers implémentés
|
||
|
|
- **Impact**: Service peut être surchargé si dépendances lentes
|
||
|
|
- **Preuve**: Pas de circuit breakers dans code
|
||
|
|
- **Cause**: Pas implémenté
|
||
|
|
- **Fix Minimal**: Implémenter circuit breaker pour Chat Server, Stream Server (ex: `github.com/sony/gobreaker`)
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Chat Server down, 10 requêtes → circuit breaker doit s'ouvrir
|
||
|
|
- Commande: Simuler Chat Server down, requêtes → doit retourner 503 rapidement
|
||
|
|
- **Effet de Bord**: Service dégradé si dépendances down (comportement attendu)
|
||
|
|
- **Effort**: M (6h)
|
||
|
|
|
||
|
|
#### MOD-P2-007: Pas de Versioning API
|
||
|
|
- **Titre**: Pas de versioning API (toutes routes `/api/v1/*`)
|
||
|
|
- **Impact**: Breaking changes difficiles. Migration clients complexe.
|
||
|
|
- **Preuve**: Toutes routes `/api/v1/*`, pas de `/api/v2/*`
|
||
|
|
- **Cause**: Versioning non planifié
|
||
|
|
- **Fix Minimal**: Documenter stratégie versioning, préparer `/api/v2/*` pour futurs breaking changes
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Route `/api/v2/*` doit exister (même impl que v1 pour l'instant)
|
||
|
|
- Commande: `curl http://localhost:8080/api/v2/health` → doit fonctionner
|
||
|
|
- **Effet de Bord**: Aucun (préparation)
|
||
|
|
- **Effort**: M (4h)
|
||
|
|
|
||
|
|
#### MOD-P2-008: Streaming Uploads/Downloads Manquant
|
||
|
|
- **Titre**: Pas de streaming uploads/downloads (fichiers chargés en mémoire)
|
||
|
|
- **Impact**: Mémoire élevée pour gros fichiers. Risque OOM.
|
||
|
|
- **Preuve**: Uploads/downloads chargent fichiers en mémoire
|
||
|
|
- **Cause**: Pas de streaming implémenté
|
||
|
|
- **Fix Minimal**: Implémenter streaming uploads/downloads avec `io.Pipe()` ou `io.Copy()`
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Uploader fichier 1GB → mémoire doit rester stable
|
||
|
|
- Commande: `curl -X POST -F "file=@large.mp3" http://localhost:8080/api/v1/tracks` → monitoring mémoire
|
||
|
|
- **Effet de Bord**: Aucun (optimisation)
|
||
|
|
- **Effort**: L (8h)
|
||
|
|
|
||
|
|
#### MOD-P2-009: Pas de Métriques DB Pool
|
||
|
|
- **Titre**: Pas de métriques DB pool (connections, wait time)
|
||
|
|
- **Impact**: Monitoring DB limité. Détection problèmes difficile.
|
||
|
|
- **Preuve**: Pool configuré mais stats pas exposées
|
||
|
|
- **Cause**: Stats pas intégrées dans Prometheus
|
||
|
|
- **Fix Minimal**: Exposer `sql.DB.Stats()` dans métriques Prometheus
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: Requêtes DB → métriques `veza_db_pool_open_connections` doivent être présentes
|
||
|
|
- Commande: `curl http://localhost:8080/metrics | grep veza_db_pool` → doit exister
|
||
|
|
- **Effet de Bord**: Aucun (ajout)
|
||
|
|
- **Effort**: S (2h)
|
||
|
|
|
||
|
|
#### MOD-P2-010: Fichiers Backup Présents
|
||
|
|
- **Titre**: Fichiers backup `.backup-pre-uuid-migration/` présents (à nettoyer)
|
||
|
|
- **Impact**: Code mort, confusion. Maintenance difficile.
|
||
|
|
- **Preuve**: Dossiers `.backup-pre-uuid-migration/` dans plusieurs endroits
|
||
|
|
- **Cause**: Migration UUID complétée mais backups non supprimés
|
||
|
|
- **Fix Minimal**: Supprimer tous dossiers `.backup-*` après vérification
|
||
|
|
- **Plan Validation**:
|
||
|
|
- Test: `find . -name ".backup-*" -type d` → doit être vide
|
||
|
|
- Commande: `git rm -r **/.backup-*` → doit supprimer
|
||
|
|
- **Effet de Bord**: Aucun (nettoyage)
|
||
|
|
- **Effort**: S (30min)
|
||
|
|
|
||
|
|
### P3 - MINEUR (Cosmétique / Refactors Non Urgents)
|
||
|
|
|
||
|
|
#### MOD-P3-001: Duplication cmd/api vs cmd/modern-server
|
||
|
|
- **Titre**: Duplication `cmd/api/main.go` vs `cmd/modern-server/main.go` (legacy?)
|
||
|
|
- **Impact**: Confusion, maintenance double. Faible impact.
|
||
|
|
- **Preuve**: Deux points d'entrée présents
|
||
|
|
- **Cause**: Migration en cours, legacy non supprimé
|
||
|
|
- **Fix Minimal**: Documenter usage, supprimer legacy si inutile
|
||
|
|
- **Effort**: S (1h)
|
||
|
|
|
||
|
|
#### MOD-P3-002: Incohérences Naming (APIRouter vs apiRouter)
|
||
|
|
- **Titre**: Incohérences naming (mix PascalCase/camelCase)
|
||
|
|
- **Impact**: Faible, confusion mineure
|
||
|
|
- **Fix Minimal**: Standardiser naming (PascalCase pour exports)
|
||
|
|
- **Effort**: S (2h)
|
||
|
|
|
||
|
|
#### MOD-P3-003: Documentation Swagger Incomplète
|
||
|
|
- **Titre**: Swagger présent mais documentation incomplète
|
||
|
|
- **Impact**: Expérience développeur dégradée
|
||
|
|
- **Fix Minimal**: Compléter annotations Swagger sur tous endpoints
|
||
|
|
- **Effort**: M (8h)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# PHASE G - PLAN D'EXÉCUTION
|
||
|
|
|
||
|
|
## G.1 Checklist P0 (Ordre Strict)
|
||
|
|
|
||
|
|
1. **MOD-P0-001**: Remplacer `panic()` par erreur dans `getEnvRequired()` (1h)
|
||
|
|
2. **MOD-P0-002**: Appliquer CORS restrictif par défaut si `CORS_ALLOWED_ORIGINS` vide (1h)
|
||
|
|
3. **MOD-P0-003**: Retourner erreur au lieu de panic dans `NewJWTService()` (30min)
|
||
|
|
|
||
|
|
**Total P0**: ~2.5h
|
||
|
|
|
||
|
|
## G.2 Checklist P1 (Par Lots Cohérents)
|
||
|
|
|
||
|
|
### Lot 1: Sécurité Auth (4h)
|
||
|
|
1. **MOD-P1-001**: Vérifier `TokenVersion` dans `AuthMiddleware` (2h)
|
||
|
|
2. **MOD-P1-002**: Valider `aud`/`iss` JWT strictement (1h)
|
||
|
|
3. **MOD-P1-003**: Rate limiting sur `/auth/login` (2h)
|
||
|
|
|
||
|
|
### Lot 2: Sécurité Input (12h)
|
||
|
|
4. **MOD-P1-004**: Intégrer scan ClamAV uploads (4h)
|
||
|
|
5. **MOD-P1-005**: Validation input systématique (8h)
|
||
|
|
|
||
|
|
### Lot 3: Observabilité (3h)
|
||
|
|
6. **MOD-P1-006**: Stack traces conditionnels selon env (1h)
|
||
|
|
7. **MOD-P1-007**: Intégrer `govulncheck` dans CI/CD (2h)
|
||
|
|
|
||
|
|
### Lot 4: Performance & Robustesse (14h)
|
||
|
|
8. **MOD-P1-008**: Audit et fix N+1 queries (6h)
|
||
|
|
9. **MOD-P1-009**: Timeout context dans tous handlers (4h)
|
||
|
|
10. **MOD-P1-010**: Rollback automatique migrations (4h)
|
||
|
|
|
||
|
|
**Total P1**: ~33h
|
||
|
|
|
||
|
|
## G.3 Quick Wins (≤ 1h chacun)
|
||
|
|
|
||
|
|
1. **MOD-P2-010**: Supprimer fichiers backup (30min)
|
||
|
|
2. **MOD-P2-002**: Validation `alg` header JWT (1h)
|
||
|
|
3. **MOD-P2-009**: Métriques DB pool (2h) - peut être split
|
||
|
|
|
||
|
|
## G.4 Tests à Ajouter en Priorité
|
||
|
|
|
||
|
|
1. **Tests P0**:
|
||
|
|
- Test config manquante → erreur claire
|
||
|
|
- Test CORS restrictif par défaut
|
||
|
|
2. **Tests P1**:
|
||
|
|
- Test token version mismatch → rejeté
|
||
|
|
- Test rate limiting login → limite appliquée
|
||
|
|
- Test scan ClamAV → fichier malveillant rejeté
|
||
|
|
- Test validation input → données invalides rejetées
|
||
|
|
3. **Tests P2**:
|
||
|
|
- Test N+1 queries → nombre queries vérifié
|
||
|
|
- Test timeout context → timeout après 30s
|
||
|
|
|
||
|
|
## G.5 PR Plan
|
||
|
|
|
||
|
|
### PR 1: Fix P0 Security (2.5h)
|
||
|
|
- **Titre**: `fix(security): Replace panics with errors in config validation`
|
||
|
|
- **Fichiers**: `internal/config/config.go`, `internal/services/jwt_service.go`, `internal/api/router.go`
|
||
|
|
- **Tests**: Tests config manquante, CORS restrictif
|
||
|
|
|
||
|
|
### PR 2: Fix P1 Auth Security (4h)
|
||
|
|
- **Titre**: `fix(security): Add token version and aud/iss validation in JWT middleware`
|
||
|
|
- **Fichiers**: `internal/middleware/auth.go`
|
||
|
|
- **Tests**: Tests token version, aud/iss validation
|
||
|
|
|
||
|
|
### PR 3: Fix P1 Rate Limiting (2h)
|
||
|
|
- **Titre**: `feat(security): Add rate limiting on /auth/login endpoint`
|
||
|
|
- **Fichiers**: `internal/api/router.go`, `internal/middleware/ratelimit.go`
|
||
|
|
- **Tests**: Tests rate limiting login
|
||
|
|
|
||
|
|
### PR 4: Fix P1 Input Validation (8h)
|
||
|
|
- **Titre**: `feat(security): Add systematic input validation with go-validator`
|
||
|
|
- **Fichiers**: `internal/dto/*.go`, `internal/handlers/*.go`, `internal/middleware/validation.go` (nouveau)
|
||
|
|
- **Tests**: Tests validation tous DTOs
|
||
|
|
|
||
|
|
### PR 5: Fix P1 Observability (3h)
|
||
|
|
- **Titre**: `fix(observability): Conditional stack traces and govulncheck integration`
|
||
|
|
- **Fichiers**: `internal/middleware/error_handler.go`, `Makefile`, `.github/workflows/ci.yml` (nouveau)
|
||
|
|
- **Tests**: Tests stack traces conditionnels
|
||
|
|
|
||
|
|
### PR 6: Fix P1 Performance (10h)
|
||
|
|
- **Titre**: `perf: Fix N+1 queries and add timeout context in handlers`
|
||
|
|
- **Fichiers**: `internal/handlers/*.go`, `internal/services/*.go`
|
||
|
|
- **Tests**: Tests nombre queries, timeout context
|
||
|
|
|
||
|
|
### PR 7: Fix P1 Migrations (4h)
|
||
|
|
- **Titre**: `fix(db): Add automatic rollback on migration failure`
|
||
|
|
- **Fichiers**: `internal/database/database.go`
|
||
|
|
- **Tests**: Tests rollback migrations
|
||
|
|
|
||
|
|
### PR 8: Quick Wins P2 (3h)
|
||
|
|
- **Titre**: `chore: Remove backup files and add JWT alg validation`
|
||
|
|
- **Fichiers**: Suppression `.backup-*`, `internal/middleware/auth.go`
|
||
|
|
- **Tests**: Tests validation alg
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## RÉSUMÉ EXÉCUTIF
|
||
|
|
|
||
|
|
### État Global
|
||
|
|
- **Build**: ✅ Compile sans erreurs
|
||
|
|
- **Tests**: ⚠️ Coverage ~45% (objectif: 80%+)
|
||
|
|
- **Sécurité**: ⚠️ 3 P0, 10 P1 identifiés
|
||
|
|
- **Robustesse**: ⚠️ Gaps observabilité, timeouts
|
||
|
|
- **Performance**: ⚠️ N+1 queries, pas de streaming
|
||
|
|
|
||
|
|
### Priorités Immédiates
|
||
|
|
1. **P0 Security** (2.5h) : Fix panics config, CORS, JWT
|
||
|
|
2. **P1 Auth Security** (4h) : Token version, aud/iss, rate limiting
|
||
|
|
3. **P1 Input Validation** (8h) : Validation systématique
|
||
|
|
4. **P1 Performance** (10h) : N+1 queries, timeouts
|
||
|
|
|
||
|
|
### Estimation Totale
|
||
|
|
- **P0**: 2.5h
|
||
|
|
- **P1**: 33h
|
||
|
|
- **P2**: ~40h
|
||
|
|
- **P3**: ~15h
|
||
|
|
- **Total**: ~90h (~11 jours développeur)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Fin du Rapport**
|
||
|
|
|