# Rapport de Pentest — VEZA v0.12.6 **Date** : 2026-03-13 **Auditeur** : Claude Code (SAST + revue manuelle de code) **Scope** : Monorepo complet — Go backend, Rust stream server, React frontend, CI/CD, infrastructure Docker **Méthodologie** : OWASP Top 10 2021, OWASP API Security Top 10 2023, ASVS Level 2 **Référence** : ORIGIN_SECURITY_FRAMEWORK.md --- ## Résumé Exécutif | Sévérité | Count | |----------|-------| | CRITICAL | 0 | | HIGH | 2 | | MEDIUM | 5 | | LOW | 4 | | INFO | 3 | | **Total findings** | **14** | | **PASS (contrôles validés)** | **18** | **Posture globale** : La codebase VEZA présente une posture de sécurité **solide** pour une RC. Aucune vulnérabilité critique n'a été identifiée. Les 2 findings HIGH concernent des fuites de métriques de popularité dans l'API publique (violation éthique) et un contournement potentiel de rate limiting via IP spoofing. Les contrôles cryptographiques, l'authentification JWT, la prévention d'injection SQL et la conformité RGPD sont bien implémentés. --- ## Findings ### HIGH-001 — IP Spoofing via X-Forwarded-For (Rate Limit Bypass) | Champ | Valeur | |-------|--------| | **Sévérité** | HIGH | | **OWASP** | API4:2023 — Unrestricted Resource Consumption | | **Fichier** | `veza-backend-api/internal/handlers/common.go:601-610` | | **CVSS** | 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) | **Description** : La méthode `GetClientIP()` lit directement le header `X-Forwarded-For` sans passer par `c.ClientIP()` de Gin, qui respecte `Engine.SetTrustedProxies`. Un attaquant peut injecter un faux header X-Forwarded-For pour contourner les rate limits basés sur l'IP. ```go // VULNÉRABLE (common.go:604) if ip := c.GetHeader("X-Forwarded-For"); ip != "" { return strings.Split(ip, ",")[0] } ``` **Impact** : Contournement complet du rate limiting pour les endpoints non authentifiés (login, register, password reset). Permet des attaques brute-force sur les credentials. **Remédiation** : Remplacer par `c.ClientIP()` et configurer `gin.Engine.SetTrustedProxies()` avec les IPs des reverse proxies de confiance. **Note** : Le middleware `metrics_protection.go:51-53` utilise correctement `c.ClientIP()` — le fix est déjà documenté dans un commentaire SECURITY(MEDIUM-002). --- ### HIGH-002 — Métriques de popularité exposées dans l'API publique | Champ | Valeur | |-------|--------| | **Sévérité** | HIGH | | **OWASP** | Business Logic Flaw | | **Fichiers** | `user_service.go:75`, `social_service.go:321`, `types/stats.go:31` | | **Réf. ORIGIN** | ORIGIN_UI_UX_SYSTEM.md §13.4, §14.2 | **Description** : Les endpoints publics de profil utilisateur (`GET /api/v1/users/:id`, `GET /api/v1/users/by-username/:username`) retournent `followers_count` et `following_count` dans la réponse JSON via `PublicUserResponse`. L'endpoint `GET /api/v1/users/suggestions` retourne aussi `followers_count` via `SuggestionUser`. Ceci viole le principe éthique fondamental de VEZA : **les métriques de popularité ne doivent JAMAIS être exposées publiquement**. **Impact** : Permet le classement social des utilisateurs, contredit les engagements éthiques de la plateforme (privacy policy §4, ORIGIN §13.4). **Remédiation** : - Supprimer `followers_count` et `following_count` de `PublicUserResponse` - Supprimer `followers_count` de `SuggestionUser` - Exposer ces métriques uniquement dans le dashboard créateur privé (derrière auth + ownership check) --- ### MEDIUM-001 — Incohérence du coût bcrypt | Champ | Valeur | |-------|--------| | **Sévérité** | MEDIUM | | **OWASP** | A02:2021 — Cryptographic Failures | | **Fichier** | `veza-backend-api/internal/core/auth/service.go:156, :986` | **Description** : Le service d'authentification utilise `bcrypt.DefaultCost` (10) pour le hachage des mots de passe lors de l'inscription et du reset, tandis que `password_service.go` utilise correctement `bcryptCost = 12`. ```go // auth/service.go:156 — coût 10 hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) // password_service.go:22 — coût 12 const bcryptCost = 12 ``` **Impact** : Les mots de passe créés via `Register()` ou `ResetPasswordWithToken()` sont 4x plus rapides à brute-forcer que ceux créés via `PasswordService.ChangePassword()`. **Remédiation** : Remplacer `bcrypt.DefaultCost` par la constante `bcryptCost` (12) dans auth/service.go, ou centraliser le hachage dans PasswordService. --- ### MEDIUM-002 — GitHub Actions non épinglées par SHA | Champ | Valeur | |-------|--------| | **Sévérité** | MEDIUM | | **OWASP** | A08:2021 — Software and Data Integrity Failures | | **Fichiers** | `sast.yml`, `security-scan.yml`, `cd.yml`, `stream-ci.yml`, `container-scan.yml`, `staging-validation.yml` | **Description** : 12+ actions GitHub sont référencées par tag (`@v3`, `@v2`, `@master`) au lieu de SHA complet. Un compromission du repo upstream permettrait l'injection de code malveillant dans le pipeline CI/CD. Actions concernées : - `github/codeql-action/*@v3` (3 usages) - `gitleaks/gitleaks-action@v2` - `docker/setup-buildx-action@v3` (2 usages) - `aquasecurity/trivy-action@0.28.0` et `@master` (5 usages) - `sigstore/cosign-installer@v3` - `actions-rust-lang/audit@v1` **Impact** : Supply chain attack sur le pipeline CI/CD. Exfiltration de secrets, injection de code dans les builds. **Remédiation** : Épingler toutes les actions par SHA (déjà fait pour `actions/checkout`, `actions/setup-go`, etc.). Utiliser Dependabot pour les mises à jour. --- ### MEDIUM-003 — CORS .env.production avec HTTP | Champ | Valeur | |-------|--------| | **Sévérité** | MEDIUM | | **OWASP** | A05:2021 — Security Misconfiguration | | **Fichier** | `veza-backend-api/.env.production:40` | **Description** : Le fichier `.env.production` contient des origines CORS en HTTP avec port 5173 (dev) : ``` CORS_ALLOWED_ORIGINS=http://veza.com:5173,http://veza.talas.fr:5173,... ``` Bien qu'un commentaire indique les valeurs HTTPS pour la production, le fichier pourrait être déployé tel quel. **Impact** : En cas de déploiement accidentel, les cookies auth pourraient être envoyés sur des connexions HTTP non chiffrées. **Remédiation** : Renommer en `.env.development` ou mettre les valeurs HTTPS par défaut avec override via variables d'environnement. --- ### MEDIUM-004 — Social Post like_count exposé publiquement | Champ | Valeur | |-------|--------| | **Sévérité** | MEDIUM | | **OWASP** | Business Logic Flaw | | **Fichier** | `veza-backend-api/internal/core/social/models.go:32` | **Description** : Le modèle `Post` (social) expose `like_count` avec `json:"like_count"` sans tag `json:"-"`. Les posts sociaux sérialisés dans les réponses API incluent le nombre de likes. Contrairement au modèle `Track` qui a correctement `json:"-"` sur `PlayCount` et `LikeCount`, les posts sociaux n'ont pas cette protection. **Impact** : Incohérence avec la politique éthique de non-exposition des métriques de popularité. **Remédiation** : Ajouter `json:"-"` au champ `LikeCount` du modèle `Post`, ou le rendre visible uniquement à l'auteur du post. --- ### MEDIUM-005 — Dashboard TrackPreview expose play_count/like_count sans ownership check granulaire | Champ | Valeur | |-------|--------| | **Sévérité** | MEDIUM | | **OWASP** | API1:2023 — Broken Object Level Authorization | | **Fichier** | `veza-backend-api/internal/handlers/dashboard.go:149-150` | **Description** : La struct `TrackPreview` expose `play_count` et `like_count` en JSON. L'endpoint dashboard (`GET /api/v1/dashboard`) est protégé par auth et retourne les tracks du user authentifié — donc c'est le créateur qui voit ses propres métriques. Cependant, si la struct `TrackPreview` est réutilisée ailleurs, les métriques fuiteraient. **Impact** : Risque faible actuellement (endpoint bien protégé), mais architecture fragile. **Remédiation** : Créer un type `TrackPreviewPublic` sans métriques pour les contextes publics, garder `TrackPreview` avec métriques uniquement pour le dashboard privé. --- ### LOW-001 — Cookie SameSite=Lax au lieu de Strict | Champ | Valeur | |-------|--------| | **Sévérité** | LOW | | **Fichier** | `veza-backend-api/internal/config/config.go:138` | **Description** : Les cookies d'authentification utilisent `SameSite=Lax` au lieu de `Strict`. Cela permet l'envoi de cookies lors de navigations top-level depuis des sites tiers (par exemple, un lien depuis un email de phishing). **Impact** : Risque CSRF résiduel pour les requêtes GET qui modifient l'état (normalement aucune dans une API REST bien conçue). **Remédiation** : Passer à `SameSite=Strict` si aucun flow OAuth/redirect externe ne nécessite `Lax`. --- ### LOW-002 — CASCADE DELETE extensif dans les migrations | Champ | Valeur | |-------|--------| | **Sévérité** | LOW | | **Fichier** | `veza-backend-api/migrations/*.sql` (30+ occurrences) | **Description** : La quasi-totalité des clés étrangères utilisent `ON DELETE CASCADE`. En cas de suppression accidentelle d'un utilisateur, toutes ses données associées (tracks, messages, playlists, orders, etc.) sont supprimées en cascade. **Impact** : Perte de données irréversible en cas d'erreur admin ou de bug dans la logique de suppression. **Remédiation** : Utiliser `ON DELETE RESTRICT` ou `ON DELETE SET NULL` pour les entités business critiques (orders, payments). Implémenter le soft delete systématiquement. --- ### LOW-003 — utils.HashPassword utilise bcrypt.DefaultCost | Champ | Valeur | |-------|--------| | **Sévérité** | LOW | | **Fichier** | `veza-backend-api/internal/utils/utils.go:57` | **Description** : La fonction utilitaire `HashPassword()` utilise `bcrypt.DefaultCost` (10). Si elle est appelée en production (au lieu de `PasswordService`), le coût sera inférieur au standard de 12. **Remédiation** : Aligner sur `bcryptCost = 12` ou supprimer cette fonction si elle n'est pas utilisée en production. --- ### LOW-004 — Staging validation workflow actions non épinglées | Champ | Valeur | |-------|--------| | **Sévérité** | LOW | | **Fichier** | `.github/workflows/staging-validation.yml:35` | **Description** : `docker/setup-buildx-action@v3` non épinglé par SHA dans le workflow de staging. **Remédiation** : Épingler par SHA comme les autres actions. --- ### INFO-001 — Binary database dump dans le repo | Champ | Valeur | |-------|--------| | **Sévérité** | INFO | | **Fichier** | `veza-backend-api/veza_back_api_db/` | **Description** : Un dump de base de données binaire est présent dans le repo. Bien que les données semblent être de développement, des informations sensibles (hashes, tokens) peuvent s'y trouver. **Remédiation** : Ajouter ce répertoire au `.gitignore` et supprimer de l'historique git avec `git filter-branch` ou BFG Repo-Cleaner. --- ### INFO-002 — hash_gen tool utilise bcrypt.DefaultCost | Champ | Valeur | |-------|--------| | **Sévérité** | INFO | | **Fichier** | `veza-backend-api/cmd/tools/hash_gen/main.go:11` | **Description** : L'outil CLI `hash_gen` utilise `bcrypt.DefaultCost`. Comme c'est un outil de développement, l'impact est nul, mais il serait bon d'aligner pour la cohérence. --- ### INFO-003 — create_test_user tool utilise bcrypt.DefaultCost | Champ | Valeur | |-------|--------| | **Sévérité** | INFO | | **Fichier** | `veza-backend-api/cmd/tools/create_test_user/main.go:54,72` | **Description** : Même constat que INFO-002 pour l'outil de création d'utilisateurs test. --- ## Contrôles Validés (PASS) | # | Contrôle | Statut | Preuve | |---|----------|--------|--------| | P01 | Injection SQL | ✅ PASS | Toutes les requêtes db.Raw() utilisent des placeholders `?`. Aucune concaténation de chaînes dans les requêtes SQL. | | P02 | Injection de commande | ✅ PASS | Aucun usage de `exec.Command`, `os/exec`, ou équivalent avec input utilisateur. | | P03 | JWT RS256 en production | ✅ PASS | `jwt_service.go` : RS256 primary, HS256 fallback dev only. | | P04 | Secrets non exposés | ✅ PASS | PasswordHash, tokens, secrets MFA ont `json:"-"`. API keys hashées. | | P05 | crypto/rand (pas math/rand) | ✅ PASS | 19 fichiers utilisent `crypto/rand`. Aucun usage de `math/rand` pour la sécurité. | | P06 | Webhook HMAC-SHA512 | ✅ PASS | Vérification HMAC correcte avec `hmac.Equal()` (timing-safe). | | P07 | Race condition prevention | ✅ PASS | `SELECT FOR UPDATE` utilisé pour les opérations concurrentes sur les soldes. | | P08 | Cookie HttpOnly | ✅ PASS | `CookieHttpOnly: true` pour access_token et refresh_token. | | P09 | Cookie Secure auto-detect | ✅ PASS | `getCookieSecure()` retourne true en production automatiquement. | | P10 | Track metrics hidden (backend) | ✅ PASS | `track.go:42-43` : PlayCount et LikeCount ont `json:"-"`. | | P11 | Rust safety | ✅ PASS | Aucun bloc `unsafe` dans `veza-stream-server/src/`. | | P12 | GDPR export | ✅ PASS | `gdpr_export_handler.go` + tests E2E. | | P13 | GDPR deletion | ✅ PASS | `account_deletion_handler.go` : anonymisation + hard delete 30j. | | P14 | Password validation | ✅ PASS | Longueur min, complexité, historique des 5 derniers, max 72 bytes (bcrypt limit). | | P15 | Rate limiting | ✅ PASS | Middleware rate limit configuré sur les endpoints sensibles. | | P16 | Security headers | ✅ PASS | HSTS, CSP, X-Frame-Options, COEP/COOP configurés. | | P17 | Container scanning | ✅ PASS | Trivy scans dans CI/CD (cd.yml, container-scan.yml). | | P18 | Secret scanning | ✅ PASS | Gitleaks action dans security-scan.yml. | --- ## Méthodologie ### Outils et techniques - **SAST** : Analyse statique manuelle du code source (Go, Rust, TypeScript) - **Pattern matching** : Recherche de patterns vulnérables (SQL concat, exec.Command, math/rand, unsafe, etc.) - **Configuration review** : Analyse des fichiers .env, Docker, CI/CD, CORS - **Architecture review** : Vérification de l'isolation des services, des contrôles d'accès, du flux de données - **Dependency analysis** : Revue des actions GitHub, crates Rust, packages npm - **ORIGIN compliance** : Vérification de la conformité avec les spécifications ORIGIN (éthique, sécurité, business logic) ### Scope couvert | Composant | Fichiers analysés | |-----------|------------------| | Go backend | ~200 fichiers .go | | Rust stream server | ~15 fichiers .rs | | React frontend | ~50 composants clés | | CI/CD | 11 workflows GitHub Actions | | Docker | 3 Dockerfiles, 3 docker-compose | | Migrations | 30+ fichiers SQL | | Configuration | .env.*, configs/ | --- *Rapport généré le 2026-03-13 — VEZA v0.12.6 Pentest Security Audit*