veza/docs/REMEDIATION_MATRIX_v0.12.6.md
senke 2a80cb4d2f feat(v0.12.6): update pentest deliverables with comprehensive 36-finding audit
Expanded from initial 14-finding analysis to full 36 findings after
6 specialized audit agents completed deep analysis.

- PENTEST_REPORT: 5 CRITICAL, 10 HIGH, 12 MEDIUM, 6 LOW, 3 INFO
- REMEDIATION_MATRIX: P0 (6h), P1 (17h), P2 (8h), P3 (10h) = ~41h total
- ASVS_CHECKLIST: 70/102 (68.6%) with 5 FAIL, 26 PARTIAL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:52:03 +01:00

144 lines
10 KiB
Markdown

# Matrice de Remédiation — VEZA v0.12.6
**Date** : 2026-03-13
**Référence** : PENTEST_REPORT_VEZA_v0.12.6.md (36 findings)
---
## Priorité de remédiation
Les actions sont classées par **priorité d'implémentation** (combinaison sévérité + facilité de fix + impact business).
---
## Actions Critiques (P0 — Immédiat, avant tout déploiement)
| ID | Finding | Sévérité | Fichier(s) | Action | Effort |
|----|---------|----------|------------|--------|--------|
| REM-001 | CRIT-001 | CRITICAL | `chat_websocket_handler.go:50`, `playback_websocket_handler.go:106`, `co_listening_websocket_handler.go:105` | Supprimer `InsecureSkipVerify: true`. Implémenter `OriginPatterns` avec whitelist des domaines autorisés. | 1h |
| REM-002 | CRIT-002 | CRITICAL | `marketplace/payout.go:175-195` | Déplacer `GetSellerBalance` DANS la transaction avec `SELECT FOR UPDATE` (`clause.Locking{Strength: "UPDATE"}`) avant validation du montant. | 2h |
| REM-003 | CRIT-003 | CRITICAL | `marketplace/service.go:1136-1189` | Wrapper lecture + validation + refund dans une seule transaction avec `SELECT FOR UPDATE` sur l'order. Vérifier `order.Status != "refunded"` atomiquement. | 2h |
| REM-004 | CRIT-004 | CRITICAL | `analytics/handler.go:727-777` | Ajouter vérification `track.CreatorID == userID` avant de retourner les analytics. Retourner 403 sinon. | 30min |
| REM-005 | CRIT-005 | CRITICAL | `handlers/marketplace.go:285-290` | Remplacer `filepath.Join(previewDir, file.Filename)` par `filepath.Join(previewDir, filepath.Base(file.Filename))` ou générer un UUID. | 15min |
**Effort total P0** : ~6h
---
## Actions Prioritaires (P1 — Avant release v1.0.0)
| ID | Finding | Sévérité | Fichier(s) | Action | Effort |
|----|---------|----------|------------|--------|--------|
| REM-006 | HIGH-001 | HIGH | `handlers/common.go:601-610` | Remplacer `c.GetHeader("X-Forwarded-For")` par `c.ClientIP()` + configurer `SetTrustedProxies()` | 1h |
| REM-007 | HIGH-002 | HIGH | `user_service.go:75`, `social_service.go:321`, `types/stats.go:31`, `social/models.go:32` | Supprimer `followers_count`/`following_count` de `PublicUserResponse` et `SuggestionUser`. Ajouter `json:"-"` sur `LikeCount` du modèle `Post`. | 2h |
| REM-008 | HIGH-003 | HIGH | `api/user/handler.go:75-95`, `api/user/service.go:188-267` | Filtrer les champs autorisés par rôle dans `UpdateMe()`. Seuls les admins peuvent modifier `role`, `is_verified`, `is_active`. | 1h |
| REM-009 | HIGH-004 | HIGH | `handlers/live_stream_callback.go:26-84` | Implémenter HMAC-SHA256 avec timestamp + body dans la signature RTMP callback. | 2h |
| REM-010 | HIGH-005 | HIGH | `auth/service.go:653-707` | Combiner validate + rotate du refresh token dans une seule transaction DB atomique. | 2h |
| REM-011 | HIGH-006 | HIGH | `marketplace/service.go:464, 764-787` | Effectuer validation et incrémentation `used_count` du promo code dans la même transaction avec `SELECT FOR UPDATE`. | 1h |
| REM-012 | HIGH-007 | HIGH | `veza-stream-server/src/auth/token_validator.rs:100-138` | Ajouter un nonce ou stocker les tokens consommés dans Redis avec TTL pour empêcher le replay. | 3h |
| REM-013 | HIGH-008 | HIGH | `handlers/account_deletion_handler.go:75-135` | Ajouter nettoyage GDPR pour orders (buyer), licenses, seller payouts, seller balance, seller transfers. Anonymiser plutôt que supprimer. | 3h |
| REM-014 | HIGH-009 | HIGH | `marketplace/service.go:610-676` | Dans `ProcessPaymentWebhook()`, comparer `order.TotalAmount` avec le montant reçu du webhook avant traitement. | 1h |
| REM-015 | HIGH-010 | HIGH | `subscription/service.go:237-251` | Déplacer la vérification du trial gratuit (`previousTrialCount`) dans la transaction avec `SELECT FOR UPDATE` sur le user. | 1h |
**Effort total P1** : ~17h
---
## Actions Recommandées (P2 — Sprint suivant)
| ID | Finding | Sévérité | Fichier(s) | Action | Effort |
|----|---------|----------|------------|--------|--------|
| REM-016 | MEDIUM-001 | MEDIUM | `auth/service.go:156, :986` | Remplacer `bcrypt.DefaultCost` par `bcryptCost` (12) importé depuis `password_service.go` ou une constante partagée. | 30min |
| REM-017 | MEDIUM-002 | MEDIUM | `sast.yml`, `security-scan.yml`, `cd.yml`, `stream-ci.yml`, `container-scan.yml`, `staging-validation.yml` | Épingler les 12+ GitHub Actions par SHA. Configurer Dependabot pour les mises à jour. | 2h |
| REM-018 | MEDIUM-003 | MEDIUM | `.env.production:40` | Renommer en `.env.local` ou `.env.development`. Mettre les valeurs HTTPS par défaut. Ajouter validation au startup. | 1h |
| REM-019 | MEDIUM-004 | MEDIUM | `docker-compose.yml:296` | Supprimer `mc anonymous set download`. Configurer des politiques MinIO par bucket avec accès authenticated uniquement. | 30min |
| REM-020 | MEDIUM-005 | MEDIUM | `api/user/handler.go`, `core/admin/handler.go`, ~15 handlers | Ajouter `max(limit, 100)` sur tous les endpoints paginés. Créer un helper `SanitizePagination()`. | 2h |
| REM-021 | MEDIUM-006 | MEDIUM | `handlers/marketplace.go:270-289` | Ajouter vérification `file.Size` avant sauvegarde dans le handler marketplace upload. | 15min |
| REM-022 | MEDIUM-007 | MEDIUM | `infra/nginx-rtmp/nginx.conf:46` | Remplacer `Access-Control-Allow-Origin: *` par la whitelist de domaines autorisés. | 15min |
| REM-023 | MEDIUM-008 | MEDIUM | `docker-compose.yml:35-56` | Ajouter `--requirepass ${REDIS_PASSWORD}` même en développement. | 15min |
| REM-024 | MEDIUM-009 | MEDIUM | `apps/web/nginx.production.conf:11-14` | Ajouter `Strict-Transport-Security` header dans la config nginx production frontend. | 15min |
| REM-025 | MEDIUM-010 | MEDIUM | `playback_websocket_handler.go:138-152` | Ajouter `conn.SetReadLimit(maxMessageSize)` pour limiter la taille des messages WebSocket. | 15min |
| REM-026 | MEDIUM-011 | MEDIUM | `marketplace/service.go:806-840` | Vérifier `license.ExpiresAt` avant de servir le téléchargement. Retourner 403 si expirée. | 30min |
| REM-027 | MEDIUM-012 | MEDIUM | `cmd/api/main.go:8` | Conditionner `import _ "net/http/pprof"` derrière un build tag `//go:build debug` ou un flag d'environnement. | 30min |
**Effort total P2** : ~8h
---
## Actions Optionnelles (P3 — Backlog)
| ID | Finding | Sévérité | Fichier(s) | Action | Effort |
|----|---------|----------|------------|--------|--------|
| REM-028 | LOW-001 | LOW | `config/config.go:138` | Passer `CookieSameSite` de `lax` à `strict` si pas de flow OAuth redirect cross-site. | 30min |
| REM-029 | LOW-002 | LOW | `migrations/*.sql` | Auditer les 30+ CASCADE DELETE. Remplacer par RESTRICT/SET NULL pour orders, payments, subscriptions. | 4h |
| REM-030 | LOW-003 | LOW | `utils/utils.go:57` | Aligner `HashPassword()` sur `bcryptCost = 12` ou la supprimer si non utilisée en prod. | 15min |
| REM-031 | LOW-004 | LOW | `staging-validation.yml:35` | Épingler `docker/setup-buildx-action` par SHA. | 10min |
| REM-032 | LOW-005 | LOW | `veza-backend-api/Dockerfile:28`, `veza-stream-server/Dockerfile:29` | Remplacer `:latest` par des tags de version spécifiques dans les Dockerfiles dev. | 15min |
| REM-033 | LOW-006 | LOW | `docker-compose.yml:171` | Remplacer le JWT_SECRET hardcodé par une variable d'environnement obligatoire, même en dev. | 15min |
| REM-034 | INFO-001 | INFO | `veza_back_api_db/` | Ajouter au `.gitignore`, purger de l'historique git avec BFG. | 1h |
| REM-035 | INFO-002 | INFO | `cmd/tools/hash_gen/main.go:11`, `cmd/tools/create_test_user/main.go:54,72` | Aligner sur `bcryptCost = 12`. | 15min |
| REM-036 | INFO-003 | INFO | `services/jwt_service.go` | Ajouter `kid` header dans les JWT et support multi-clés pour faciliter la rotation. | 3h |
**Effort total P3** : ~10h
---
## Résumé par effort
| Priorité | Findings | Effort total |
|----------|----------|--------------|
| P0 (Immédiat — bloquant) | 5 CRITICAL | ~6h |
| P1 (Avant v1.0.0) | 10 HIGH | ~17h |
| P2 (Sprint suivant) | 12 MEDIUM | ~8h |
| P3 (Backlog) | 9 LOW/INFO | ~10h |
| **Total** | **36** | **~41h** |
---
## Workflow de remédiation
```
── P0 CRITICAL (Jour 1) ──────────────────────────────────
1. REM-005 (Path traversal) → Test: upload fichier avec ../ dans le nom
2. REM-004 (Analytics IDOR) → Test: accéder aux analytics d'une track d'un autre user
3. REM-001 (WebSocket CSWSH) → Test: connexion WS depuis un domaine non autorisé
4. REM-002 (Payout race) → Test: 2 payouts simultanés, vérifier solde cohérent
5. REM-003 (Refund race) → Test: 2 refunds simultanés, vérifier un seul traité
── P1 HIGH (Semaine 1) ───────────────────────────────────
6. REM-006 (IP spoofing) → Test: rate limit avec X-Forwarded-For forgé
7. REM-007 (Popularity metrics) → Test: /api/v1/users/:id ne retourne plus followers_count
8. REM-008 (Mass assignment) → Test: PUT /api/v1/users/me avec {"role":"admin"} = rejeté
9. REM-010 (Refresh token race) → Test: 2 refresh simultanés, un seul réussit
10. REM-014 (Webhook amount) → Test: webhook avec montant différent = rejeté
11. REM-011 (Promo code race) → Test: 2 uses simultanées, max_uses respecté
12. REM-015 (Free trial race) → Test: 2 souscriptions trial simultanées, une seule OK
13. REM-009 (RTMP auth) → Test: callback avec signature invalide = rejeté
14. REM-012 (Stream replay) → Test: URL rejouée après consommation = rejetée
15. REM-013 (GDPR financier) → Test: suppression compte, vérifier données financières anonymisées
── P2 MEDIUM (Sprint suivant) ────────────────────────────
16-27. REM-016 à REM-027 → Tests spécifiques par finding
```
---
## Métriques de suivi
| Métrique | Valeur actuelle | Cible v1.0.0 |
|----------|----------------|---------------|
| Findings CRITICAL | 5 | 0 |
| Findings HIGH | 10 | 0 |
| Findings MEDIUM | 12 | 0 |
| Findings LOW | 6 | ≤ 2 |
| Findings INFO | 3 | ≤ 3 |
| Race conditions financières | 4 (payout, refund, promo, trial) | 0 |
| WebSocket origin validation | 0/3 handlers | 3/3 handlers |
| Actions pinned by SHA | ~60% | 100% |
| bcrypt cost consistency | 2 valeurs (10, 12) | 1 valeur (12) |
| Public popularity metrics | 3 endpoints | 0 endpoints |
| IDOR vulnerabilities | 1 (analytics) | 0 |
---
*Matrice générée le 2026-03-13 — VEZA v0.12.6 — 36 findings*