veza/docs/archive/REMEDIATION_MATRIX_v0.12.6.md
senke 47afb055a2 chore(docs): archive obsolete v0.12.6 security docs
Move ASVS_CHECKLIST_v0.12.6.md, PENTEST_REPORT_VEZA_v0.12.6.md, and
REMEDIATION_MATRIX_v0.12.6.md to docs/archive/ — all reference a
pentest conducted on v0.12.6 (2026-03), stale relative to the current
v1.0.7 codebase (different security middleware, different payment
flow, different config validation).

Update CLAUDE.md tree listing and AUDIT_REPORT.md §9.1 to reflect the
archive location. Keep docs/SECURITY_SCAN_RC1.md (still current).

Closes AUDIT_REPORT §9.1 obsolete-doc item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:32:25 +02:00

10 KiB

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