562 lines
32 KiB
Markdown
562 lines
32 KiB
Markdown
|
|
I'll conduct this comprehensive technical audit by systematically exploring every layer of your monorepo. Let me start by gathering all the critical information in parallel.
|
||
|
|
|
||
|
|
[5 tools called]
|
||
|
|
|
||
|
|
Now let me dive deeper into specific security and infrastructure concerns.
|
||
|
|
|
||
|
|
[6 tools called]
|
||
|
|
|
||
|
|
Now let me write the complete audit report. Given the massive amount of data collected, I'll produce the full structured document.
|
||
|
|
|
||
|
|
[1 tool called]
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# AUDIT TECHNIQUE INTÉGRAL — MONOREPO VEZA
|
||
|
|
|
||
|
|
**Date :** 14 février 2026
|
||
|
|
**Auditeur :** Analyse automatisée exhaustive du code source
|
||
|
|
**Périmètre :** Monorepo complet (`/home/senke/git/talas/veza`)
|
||
|
|
**Classification :** Confidentiel — Comité d'investissement
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## EXECUTIVE SUMMARY
|
||
|
|
|
||
|
|
Veza est une **plateforme audio collaborative** (type SoundCloud/Bandcamp) avec marketplace, chat temps réel, streaming audio, social, et éducation. Le monorepo contient 4 services (Go API, 2 serveurs Rust, frontend React) et un site documentation.
|
||
|
|
|
||
|
|
**Verdict global : Le produit est fonctionnel mais pas prêt pour la production.**
|
||
|
|
|
||
|
|
Le backend Go est le composant le plus mature (150+ endpoints, tests solides, sécurité raisonnable). Le frontend est ambitieux mais contient ~150 fichiers de code mort. Les services Rust ont des TODOs critiques non résolus. Trois vulnérabilités de sécurité **critiques** ont été identifiées, toutes liées à des bypasses de développement laissés actifs.
|
||
|
|
|
||
|
|
| Dimension | Score |
|
||
|
|
|-----------|-------|
|
||
|
|
| Architecture | 6/10 |
|
||
|
|
| Maintenabilité | 5/10 |
|
||
|
|
| Sécurité | 5/10 |
|
||
|
|
| Scalabilité | 7/10 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. CARTOGRAPHIE GLOBALE
|
||
|
|
|
||
|
|
### Stack technique complète
|
||
|
|
|
||
|
|
| Couche | Technologie | Version |
|
||
|
|
|--------|-------------|---------|
|
||
|
|
| **Frontend** | React + TypeScript | 18.2.0 / 5.3.3 |
|
||
|
|
| **Build** | Vite | 7.1.5 |
|
||
|
|
| **CSS** | Tailwind CSS | 4.0.0 |
|
||
|
|
| **State** | Zustand | 4.5.0 |
|
||
|
|
| **Data** | TanStack Query | 5.17.0 |
|
||
|
|
| **Forms** | React Hook Form + Zod | 7.49.3 / 3.25.76 |
|
||
|
|
| **Tests frontend** | Vitest + Playwright + Storybook | 3.2.4 / 1.58.2 / 8.6.15 |
|
||
|
|
| **Backend API** | Go + Gin | 1.23.8 / 1.11.0 |
|
||
|
|
| **ORM** | GORM | 1.30.0 |
|
||
|
|
| **Chat Server** | Rust + Axum | edition 2021 / 0.8 |
|
||
|
|
| **Stream Server** | Rust + Axum + Symphonia | edition 2021 / 0.8 / 0.5 |
|
||
|
|
| **Base de données** | PostgreSQL | 16 |
|
||
|
|
| **Cache** | Redis | 7 |
|
||
|
|
| **Message broker** | RabbitMQ | 3 |
|
||
|
|
| **Storage** | AWS S3 | SDK v2 |
|
||
|
|
| **Monitoring** | Prometheus + Sentry | - |
|
||
|
|
| **CI/CD** | GitHub Actions | 11 workflows |
|
||
|
|
| **Conteneurs** | Docker + Kubernetes | Multi-stage builds |
|
||
|
|
| **Documentation** | Docusaurus + Storybook | 3.8.1 / 8.6.15 |
|
||
|
|
|
||
|
|
### Organisation du monorepo
|
||
|
|
|
||
|
|
```
|
||
|
|
veza/
|
||
|
|
├── apps/web/ # Frontend React (799 composants TSX)
|
||
|
|
├── veza-backend-api/ # API Go (88 handlers, 163 services, 49 middlewares)
|
||
|
|
├── veza-chat-server/ # Chat WebSocket Rust
|
||
|
|
├── veza-stream-server/ # Audio streaming Rust
|
||
|
|
├── veza-common/ # Bibliothèque Rust partagée
|
||
|
|
├── veza-docs/ # Documentation Docusaurus
|
||
|
|
├── fixtures/ # Seeding & fixtures
|
||
|
|
├── config/docker/ # Configs Docker
|
||
|
|
├── infra/ # Configs infra lab
|
||
|
|
├── scripts/ # Scripts utilitaires
|
||
|
|
├── make/ # Modules Makefile
|
||
|
|
└── .github/workflows/ # 11 workflows CI/CD
|
||
|
|
```
|
||
|
|
|
||
|
|
### Outil monorepo
|
||
|
|
|
||
|
|
**npm workspaces** uniquement pour le frontend. Go et Rust sont gérés indépendamment. Pas de Turborepo, Nx, ou Lerna. C'est essentiellement un **poly-repo déguisé en monorepo** — seul `apps/web` bénéficie réellement du workspace. Les services Go et Rust n'ont aucun lien de build partagé avec le frontend.
|
||
|
|
|
||
|
|
### Dépendance potentiellement abandonnée
|
||
|
|
|
||
|
|
- **`github.com/Lyimmi/go-clamd v1.0.0`** — dernière mise à jour 2017 (scan antivirus ClamAV). Risque : vulnérabilités non corrigées, pas de maintenance.
|
||
|
|
|
||
|
|
### Flux de données
|
||
|
|
|
||
|
|
```
|
||
|
|
Browser → React (Vite) → Axios + httpOnly cookies
|
||
|
|
↓
|
||
|
|
Go API (Gin) ← JWT ← PostgreSQL ← GORM
|
||
|
|
↓
|
||
|
|
Redis (cache, rate limit, sessions)
|
||
|
|
RabbitMQ (event bus)
|
||
|
|
AWS S3 (fichiers audio)
|
||
|
|
ClamAV (scan antivirus)
|
||
|
|
↓
|
||
|
|
Chat Server (Rust/Axum) ← WebSocket ← JWT
|
||
|
|
Stream Server (Rust/Axum) ← WebSocket/HLS ← JWT
|
||
|
|
↓
|
||
|
|
PostgreSQL (messages, streams)
|
||
|
|
Redis (présence, sync)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. CE QUE LE PRODUIT PERMET RÉELLEMENT
|
||
|
|
|
||
|
|
### Features validées (fonctionnelles, routes + backend + frontend)
|
||
|
|
|
||
|
|
| Feature | Backend | Frontend | Tests |
|
||
|
|
|---------|---------|----------|-------|
|
||
|
|
| Authentification (login, register, 2FA, OAuth) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Gestion de profil | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Upload et gestion de tracks | ✅ Complet (chunked) | ✅ Complet | ✅ |
|
||
|
|
| Playlists (CRUD, collaboratifs, export) | ✅ Complet | ✅ Complet | ⚠️ 3 tests skip |
|
||
|
|
| Marketplace (produits, commandes, panier) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Chat temps réel (WebSocket) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Recherche (tracks, users, playlists) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Notifications | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Social (feed, posts, likes, groupes) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Webhooks (CRUD, test, stats) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Analytics et dashboard | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Sessions (gestion, révocation) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Settings utilisateur | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Admin dashboard | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Rôles et permissions (RBAC) | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
| Audit trail | ✅ Complet | ✅ Complet | ✅ |
|
||
|
|
|
||
|
|
### Features partiellement implémentées
|
||
|
|
|
||
|
|
| Feature | État | Détail |
|
||
|
|
|---------|------|--------|
|
||
|
|
| Streaming HLS | ⚠️ Backend complet, feature flag OFF | `HLS_STREAMING: false` dans `config/features.ts` |
|
||
|
|
| Playlist Search | ⚠️ Backend complet, feature flag OFF | `PLAYLIST_SEARCH: false` (activé seulement en Storybook) |
|
||
|
|
| Playlist Recommendations | ⚠️ Backend complet, feature flag OFF | `PLAYLIST_RECOMMENDATIONS: false` |
|
||
|
|
| Role Management UI | ⚠️ Backend complet, feature flag OFF | `ROLE_MANAGEMENT: false` |
|
||
|
|
| Audio transcoding | ⚠️ Pipeline stub | `core/encoding_pool.rs:141` — TODO: implémenter la création réelle du pipeline |
|
||
|
|
| Developer API Keys | ⚠️ Frontend localStorage | Pas de persistance backend pour les clés API |
|
||
|
|
|
||
|
|
### Features fantômes (code présent, inaccessible)
|
||
|
|
|
||
|
|
| Feature | Fichiers | Problème |
|
||
|
|
|---------|----------|----------|
|
||
|
|
| **Studio** | 93+ fichiers dans `src/components/studio/` | Aucune route dans `routeConfig.tsx`. Feature entièrement implémentée côté UI mais **inaccessible** |
|
||
|
|
| **Gamification** | `gamificationService.ts`, `LeaderboardView`, `AchievementsView` | Service mock, TODO: "Implement with real API endpoints when backend is ready" |
|
||
|
|
| **Cloud Storage** | `storageService.ts`, `CloudFileBrowser` | Service mock avec données hardcodées |
|
||
|
|
| **Projects Manager** | `projectService.ts`, `ProjectsManager` | Service mock, lié au Studio fantôme |
|
||
|
|
|
||
|
|
### Features mortes / deprecated
|
||
|
|
|
||
|
|
| Feature | Fichier | État |
|
||
|
|
|---------|---------|------|
|
||
|
|
| `Modal` composant | `src/components/ui/modal.tsx` | `@deprecated S1.4: Prefer using Dialog` — encore utilisé |
|
||
|
|
| `ToastProvider` | `src/components/feedback/ToastProvider.tsx` | `@deprecated S1.2: Use useToast` — encore importé |
|
||
|
|
| `aggressiveVisualFix` | `src/utils/aggressiveVisualFix.ts` | Deprecated, fix visuel agressif |
|
||
|
|
| Legacy chat tables | `migrations/050_legacy_chat.sql` | Tables legacy coexistant avec le chat Rust |
|
||
|
|
|
||
|
|
### Incohérences produit/code
|
||
|
|
|
||
|
|
1. **19 fichiers de tests exclus** dans `vitest.config.ts` pour des composants non implémentés (CommentForm, PlaysChart, TrackEdit, TrackUpload, HLSPlayer, ProfileEditForm, etc.)
|
||
|
|
2. **3 services mock-only** (`gamificationService`, `projectService`, `storageService`) référencés par des composants actifs
|
||
|
|
3. **100+ commentaires TODO/FIXME** non résolus dans le frontend
|
||
|
|
4. **7 tests skippés** dans les suites Vitest actives
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. VALIDATION FONCTIONNELLE
|
||
|
|
|
||
|
|
### Couverture des tests
|
||
|
|
|
||
|
|
| Couche | Tests unitaires | Tests intégration | Tests E2E | Seuil couverture |
|
||
|
|
|--------|----------------|-------------------|-----------|-----------------|
|
||
|
|
| Backend Go | 88 fichiers handler + 163 fichiers service | ✅ `tests/api_routes_integration_test.go` | - | Non configuré |
|
||
|
|
| Frontend | 286 fichiers `.test.ts/.tsx` | - | ✅ Playwright (4 navigateurs) | 80% (branches, functions, lines) |
|
||
|
|
| Chat Rust | Tests unitaires présents | - | - | Non configuré |
|
||
|
|
| Stream Rust | Tests unitaires présents | - | - | Non configuré |
|
||
|
|
| Stories | 323 fichiers `.stories.tsx` | - | - | - |
|
||
|
|
|
||
|
|
### Points de rupture identifiés
|
||
|
|
|
||
|
|
1. **Rate limiting fail-open** — Si Redis est indisponible, le rate limiting du chat server est désactivé silencieusement (`handler.rs:299`). Un attaquant peut flood le service pendant un incident Redis.
|
||
|
|
|
||
|
|
2. **Account lockout fail-open** — Si Redis est indisponible, le lockout de comptes est désactivé (`account_lockout_service.go:89-94`). Brute force possible pendant un incident Redis.
|
||
|
|
|
||
|
|
3. **INTERNAL_API_KEY optionnel** — Le stream server n'exige pas cette clé pour les callbacks vers le backend (`compression.rs:536`). Les notifications de transcoding peuvent échouer silencieusement.
|
||
|
|
|
||
|
|
4. **Migration relative path** — `database.go:239` utilise `filepath.Glob("migrations/*.sql")` avec un chemin relatif. Si le binaire est lancé depuis un répertoire différent, les migrations échouent.
|
||
|
|
|
||
|
|
### Scénarios de crash évidents
|
||
|
|
|
||
|
|
1. **Dual migration numbers** — Les migrations `020_create_sessions.sql` et `020_rbac_and_profiles.sql` ont le même préfixe. L'ordre alphabétique peut créer des incohérences de schéma.
|
||
|
|
2. **Idem pour** `050_data_validation_constraints.sql` et `050_legacy_chat.sql`.
|
||
|
|
3. **Pas de migrations down** — Aucun rollback possible en cas de migration défaillante.
|
||
|
|
|
||
|
|
### Zones non testées
|
||
|
|
|
||
|
|
- 19 composants frontend référencés dans `vitest.config.ts` comme exclus
|
||
|
|
- Studio feature (93+ fichiers, 0 test)
|
||
|
|
- Pipeline d'encodage audio (stub)
|
||
|
|
- Gamification service (mock)
|
||
|
|
- Intégration ClamAV end-to-end
|
||
|
|
- WebSocket stream server rate limiting
|
||
|
|
- Rollback de migration
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. AUDIT DE SÉCURITÉ — OWASP TOP 10
|
||
|
|
|
||
|
|
### A01 — Broken Access Control
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| **Dev bypass role check** | **CRITIQUE** | `middleware/auth.go:440-451` | En mode `development`, TOUS les checks de rôle sont bypassed. Si `APP_ENV=development` en production → accès total. |
|
||
|
|
| **Dev bypass CSRF** | **CRITIQUE** | `middleware/csrf.go:44-47` | CSRF désactivé si `env == "development"`. Misconfiguration = CSRF exploitable. |
|
||
|
|
| Ownership checks | OK | Handlers | Les routes de modification vérifient la propriété (ownership middleware). |
|
||
|
|
| Admin routes | OK | `router.go` | Routes admin protégées par middleware admin. |
|
||
|
|
| IDOR potentiel | Faible | Handlers profil | `PUT /api/v1/users/:id` vérifie ownership. Pas de IDOR évident. |
|
||
|
|
|
||
|
|
**Scénario d'exploitation A01 :** Un attaquant découvre que l'environnement de staging/preprod est configuré avec `APP_ENV=development`. Il peut alors bypasser toutes les vérifications de rôle et créer du contenu, accéder aux routes admin, et contourner la protection CSRF.
|
||
|
|
|
||
|
|
### A02 — Cryptographic Failures
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| Bcrypt cost 12 | OK | `password_service.go:21` | Acceptable |
|
||
|
|
| JWT HS256 | OK | `jwt_service.go:127` | Validation stricte de l'algorithme |
|
||
|
|
| JWT secret min 32 chars | OK | `config.go` | Validé au démarrage |
|
||
|
|
| **Password truncation silencieuse** | **Élevée** | `password_service.go:299-303` | Mots de passe > 72 bytes tronqués sans erreur. L'utilisateur croit être protégé par un mot de passe long. |
|
||
|
|
| Chat JWT secret fallback | Moyenne | `config.go:262` | Si `CHAT_JWT_SECRET` non défini, utilise le secret principal. Blast radius augmenté. |
|
||
|
|
| Tokens httpOnly cookies | OK | Frontend | Tokens non accessibles en JS |
|
||
|
|
| HTTPS (HSTS) | OK | `security_headers.go` | En production uniquement |
|
||
|
|
|
||
|
|
### A03 — Injection
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| SQL injection | Faible | Backend Go | GORM paramétrise les requêtes. Raw SQL utilise `$1, $2` placeholders. |
|
||
|
|
| SQL injection (Rust) | Faible | Chat/Stream | SQLx avec requêtes paramétrées. |
|
||
|
|
| XSS | Faible | Frontend | DOMPurify sur `dangerouslySetInnerHTML`. Config stricte. |
|
||
|
|
| NoSQL injection | N/A | - | Pas de NoSQL |
|
||
|
|
| Command injection | Faible | `compression.rs` | FFmpeg exécuté via commande système mais avec paramètres contrôlés |
|
||
|
|
|
||
|
|
### A04 — Insecure Design
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| **Rate limit bypass via headers** | **CRITIQUE** | `rate_limiter.go:94-104` | Headers `X-Test-Mode: true` ou `X-E2E-Test: true` désactivent le rate limiting. Un attaquant peut envoyer ces headers. |
|
||
|
|
| Rate limiting present | OK | Auth endpoints | EndpointLimiter avec limites configurées |
|
||
|
|
| Input validation | OK | Validators, Zod | Validation côté serveur et client |
|
||
|
|
| Account lockout | OK | `account_lockout_service.go` | 5 tentatives / 30 min lockout |
|
||
|
|
|
||
|
|
**Scénario d'exploitation A04 :** Un attaquant envoie `X-Test-Mode: true` dans ses requêtes HTTP. Le rate limiter du backend Go est immédiatement désactivé. L'attaquant peut alors brute-forcer les identifiants sans restriction.
|
||
|
|
|
||
|
|
### A05 — Security Misconfiguration
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| **Debug print en production** | Faible | `auth.go:88` | `fmt.Println("DEBUG: Using c.JSON(401)")` laissé dans le code |
|
||
|
|
| JWT secrets hardcodés (dev) | Faible | `docker-compose.yml:98` | `dev-secret-key-minimum-32-characters-long` — acceptable en dev |
|
||
|
|
| Grafana default password | Faible | Docker compose locaux | `admin/admin` — dev uniquement |
|
||
|
|
| Elasticsearch security off | Faible | `docker-compose.local.yml:72` | Dev uniquement |
|
||
|
|
| CORS validé en production | OK | `cors.go`, `config.go` | Pas de wildcard en production |
|
||
|
|
| Security headers | OK | `security_headers.go` | CSP, HSTS, X-Frame-Options, etc. |
|
||
|
|
|
||
|
|
### A06 — Vulnerable & Outdated Components
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| `go-clamd v1.0.0` | Moyenne | `go.mod` | Abandonné depuis 2017, risque de vulnérabilités |
|
||
|
|
| CI scanning | OK | CI workflows | `govulncheck`, `cargo audit`, `npm audit` exécutés |
|
||
|
|
| Trivy scanning | Partiel | Stream server seulement | Main CD pipeline n'a pas de scan Trivy |
|
||
|
|
|
||
|
|
### A07 — Identification & Authentication Failures
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| JWT token versioning | OK | `jwt_service.go`, `auth.go:136` | Révocation via version |
|
||
|
|
| Session management | OK | `session_service.go` | Auto-refresh, révocation |
|
||
|
|
| Password reset anti-enum | OK | `auth/service.go:806-814` | Retourne nil si user non trouvé |
|
||
|
|
| **Timing attack CSRF** | **Élevée** | `csrf.go:122` | Comparaison string non constant-time. `if storedToken != token` |
|
||
|
|
| **Session refresh race** | Moyenne | `auth.go:199-216` | Goroutine sans mutex. Refreshs concurrents possibles. |
|
||
|
|
| 2FA implémenté | OK | `twoFactorHandler` | TOTP complet |
|
||
|
|
|
||
|
|
### A08 — Software & Data Integrity Failures
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| **Pas de signature d'images Docker** | Moyenne | `.github/workflows/cd.yml` | Images poussées sans cosign |
|
||
|
|
| CI/CD avec secrets GitHub | OK | Workflows | Secrets gérés via GitHub |
|
||
|
|
| Input validation backend | OK | Validators, binding tags | Validation serveur systématique |
|
||
|
|
|
||
|
|
### A09 — Logging & Monitoring Failures
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| Structured logging | OK | Zap (Go), tracing (Rust) | Logs structurés partout |
|
||
|
|
| Audit trail | OK | `audit_handler.go`, `audit_service.go` | Logs d'audit avec détection activités suspectes |
|
||
|
|
| Sentry integration | OK | Frontend + Backend | Error tracking |
|
||
|
|
| Prometheus metrics | OK | Tous les services | Métriques exposées |
|
||
|
|
| **Info disclosure lockout** | Faible | `auth/service.go:438` | Message d'erreur révèle la durée du lockout |
|
||
|
|
|
||
|
|
### A10 — SSRF
|
||
|
|
|
||
|
|
| Vulnérabilité | Gravité | Fichier | Détail |
|
||
|
|
|---------------|---------|---------|--------|
|
||
|
|
| Webhook URLs | Moyenne | `webhook.go` | URLs de webhook fournies par l'utilisateur. Vérifier si les URLs internes sont filtrées. |
|
||
|
|
| OAuth callbacks | OK | `oauthHandler` | Providers configurés côté serveur |
|
||
|
|
| Stream callbacks | OK | Internal routes | Authentifié par API key interne |
|
||
|
|
|
||
|
|
### Résumé sécurité
|
||
|
|
|
||
|
|
| Catégorie | Critique | Élevée | Moyenne | Faible |
|
||
|
|
|-----------|----------|--------|---------|--------|
|
||
|
|
| A01 - Access Control | 2 | 0 | 0 | 0 |
|
||
|
|
| A02 - Crypto | 0 | 1 | 1 | 0 |
|
||
|
|
| A03 - Injection | 0 | 0 | 0 | 1 |
|
||
|
|
| A04 - Insecure Design | 1 | 0 | 0 | 0 |
|
||
|
|
| A05 - Misconfig | 0 | 0 | 0 | 3 |
|
||
|
|
| A06 - Outdated | 0 | 0 | 1 | 0 |
|
||
|
|
| A07 - Auth Failures | 0 | 1 | 1 | 0 |
|
||
|
|
| A08 - Integrity | 0 | 0 | 1 | 0 |
|
||
|
|
| A09 - Logging | 0 | 0 | 0 | 1 |
|
||
|
|
| A10 - SSRF | 0 | 0 | 1 | 0 |
|
||
|
|
| **TOTAL** | **3** | **2** | **5** | **5** |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. DETTE TECHNIQUE
|
||
|
|
|
||
|
|
### Dette critique (bloquante)
|
||
|
|
|
||
|
|
| Problème | Fichier(s) | Impact |
|
||
|
|
|----------|-----------|--------|
|
||
|
|
| **3 bypasses sécurité pilotés par env** | `rate_limiter.go`, `csrf.go`, `auth.go` | Exploitation possible si env mal configuré |
|
||
|
|
| **Duplicate migration numbers** | `020_*.sql`, `050_*.sql` | Schéma DB potentiellement incohérent |
|
||
|
|
| **Pas de migrations down** | `migrations/` | Impossible de rollback une migration en erreur |
|
||
|
|
| **Pipeline encoding stub** | `encoding_pool.rs:141` | Transcoding audio non fonctionnel |
|
||
|
|
| **93+ fichiers Studio fantômes** | `components/studio/` | ~150 fichiers de code mort inaccessible |
|
||
|
|
|
||
|
|
### Dette structurante
|
||
|
|
|
||
|
|
| Problème | Fichier(s) | Impact |
|
||
|
|
|----------|-----------|--------|
|
||
|
|
| 19 tests exclus pour composants non implémentés | `vitest.config.ts` | Tests écrits pour du code qui n'existe pas |
|
||
|
|
| 7 tests skippés | Suites Vitest | Régressions non détectées |
|
||
|
|
| Services mock-only (gamification, projects, storage) | `src/services/` | Features fantômes visibles dans l'UI |
|
||
|
|
| Composants deprecated encore utilisés (Modal, ToastProvider) | `modal.tsx`, `ToastProvider.tsx` | Double implémentation, confusion |
|
||
|
|
| 100+ TODO/FIXME non résolus | Frontend entier | Travail inachevé accumulé |
|
||
|
|
| Repository pattern incomplet | `internal/repositories/` | Track, Notification, Webhook, Role n'ont pas de repository dédié |
|
||
|
|
| Monorepo sans orchestration | Racine | Go et Rust indépendants, pas de build unifié |
|
||
|
|
| Feature flags pour features backend-ready | `config/features.ts` | 4 features désactivées côté frontend alors que le backend est prêt |
|
||
|
|
| `router.go` : 1576 lignes | `internal/api/router.go` | Fichier massif, difficile à maintenir |
|
||
|
|
| Chat server legacy modules | `security_legacy.rs`, `auth.rs` | Code mort dans le serveur Rust |
|
||
|
|
|
||
|
|
### Dette cosmétique
|
||
|
|
|
||
|
|
| Problème | Fichier(s) | Impact |
|
||
|
|
|----------|-----------|--------|
|
||
|
|
| Debug print laissé | `auth.go:88` | Pollution des logs |
|
||
|
|
| Info disclosure lockout duration | `auth/service.go:438` | Fuite d'information mineure |
|
||
|
|
| Composants > 300 lignes | Plusieurs fichiers | Non-conformité aux règles projet |
|
||
|
|
| Duplicate skeleton patterns | Composants studio/views | Patterns répétitifs non factorisés |
|
||
|
|
| Convention mixte (anglais/français) | Commentaires, docs | Incohérence linguistique |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. QUALITÉ ARCHITECTURALE
|
||
|
|
|
||
|
|
### Frontend — Structure
|
||
|
|
|
||
|
|
Le frontend suit une organisation **features-first** avec séparation claire entre composants UI, features métier, services, hooks, et stores. React Router avec lazy loading systématique. Zustand pour le state, TanStack Query pour le data fetching. MSW pour les mocks (1737 lignes de handlers). Storybook obligatoire pour les composants.
|
||
|
|
|
||
|
|
**Points forts :** Séparation des responsabilités claire. Lazy loading systématique. DOMPurify pour la sanitization. CSRF géré côté client. httpOnly cookies.
|
||
|
|
|
||
|
|
**Points faibles :** 799 composants TSX — volume massif. 93+ fichiers Studio fantômes. 3 services mock-only. Composants deprecated non nettoyés.
|
||
|
|
|
||
|
|
### Backend — Structure
|
||
|
|
|
||
|
|
Architecture **handlers → services → repositories → database** classique et propre. 150+ endpoints bien organisés. Middleware stack complète (CORS, CSRF, rate limiting, auth, security headers, metrics, logging). Migrations SQL manuelles (pas d'outil type golang-migrate). GORM pour l'ORM avec raw SQL quand nécessaire.
|
||
|
|
|
||
|
|
**Points forts :** Sécurité mature (JWT versioning, account lockout, audit trail). 88 handlers testés. Séparation propre des couches.
|
||
|
|
|
||
|
|
**Points faibles :** `router.go` à 1576 lignes. Repository pattern incomplet. Migrations avec numéros dupliqués. Pas de down migrations.
|
||
|
|
|
||
|
|
### Services Rust — Structure
|
||
|
|
|
||
|
|
Architecture Axum/Tokio correcte. Gestion d'erreurs avec types dédiés. Logging structuré via `tracing`. Event bus RabbitMQ avec dégradation gracieuse.
|
||
|
|
|
||
|
|
**Points forts :** Requêtes SQL paramétrées. Signatures timing-safe (stream server). Rate limiting granulaire (chat server).
|
||
|
|
|
||
|
|
**Points faibles :** Timeouts hardcodés. Rate limiting fail-open. Pipeline d'encodage stub. Modules legacy.
|
||
|
|
|
||
|
|
### CI/CD
|
||
|
|
|
||
|
|
11 workflows GitHub Actions. Scanning de sécurité (`govulncheck`, `cargo audit`, `npm audit`, Trivy partiel). Pipeline complète : lint → test → build → deploy.
|
||
|
|
|
||
|
|
**Points faibles :** Pas de Trivy dans le CD principal. Pas de signature d'images. Pas de SBOM.
|
||
|
|
|
||
|
|
### Scores
|
||
|
|
|
||
|
|
| Dimension | Score | Justification |
|
||
|
|
|-----------|-------|---------------|
|
||
|
|
| **Architecture** | **6/10** | Bonne séparation des couches, mais monorepo sans orchestration réelle. Go et Rust isolés. Studio fantôme pollue la base de code. Router.go monolithique. |
|
||
|
|
| **Maintenabilité** | **5/10** | 100+ TODOs, 150+ fichiers morts, composants deprecated, tests exclus/skippés, conventions mixtes français/anglais, pas de down migrations. |
|
||
|
|
| **Sécurité** | **5/10** | Fondations solides (JWT versioning, bcrypt, security headers, audit trail) MAIS 3 vulnérabilités critiques (bypasses dev), timing attack CSRF, fail-open patterns. |
|
||
|
|
| **Scalabilité** | **7/10** | Architecture microservices appropriée. PostgreSQL + Redis + RabbitMQ. Code splitting frontend. HLS streaming prévu. Prometheus metrics. Kubernetes-ready. Manque le pipeline d'encodage réel. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. INFRA & DEVOPS
|
||
|
|
|
||
|
|
### Docker
|
||
|
|
|
||
|
|
**Positif :**
|
||
|
|
- Multi-stage builds sur tous les services (images optimisées)
|
||
|
|
- Utilisateurs non-root dans tous les Dockerfiles
|
||
|
|
- Health checks configurés partout
|
||
|
|
- Isolation réseau via `veza-net`
|
||
|
|
- Resource limits configurés
|
||
|
|
- Fichiers de production séparés des fichiers de dev
|
||
|
|
|
||
|
|
**Négatif :**
|
||
|
|
- Secrets hardcodés dans les docker-compose dev (acceptable mais risque de copier en prod)
|
||
|
|
- Grafana avec password `admin` dans les configs monitoring locales
|
||
|
|
- Elasticsearch security désactivé en local
|
||
|
|
|
||
|
|
### Gestion des environnements
|
||
|
|
|
||
|
|
- **dev** : `docker-compose.yml` — secrets hardcodés, acceptable
|
||
|
|
- **test** : `docker-compose.test.yml` — tmpfs, credentials test
|
||
|
|
- **staging** : `docker-compose.staging.yml` — variables d'environnement requises
|
||
|
|
- **production** : `docker-compose.prod.yml` — validation des variables (`${DB_PASS:?DB_PASS must be set}`), SSL obligatoire
|
||
|
|
|
||
|
|
**La chaîne dev → staging → prod est cohérente.** Le code valide bien les variables critiques en production (`config.go:141-198`).
|
||
|
|
|
||
|
|
### Secrets
|
||
|
|
|
||
|
|
- `.gitignore` exclut correctement tous les `.env*` et le répertoire `secrets/`
|
||
|
|
- Pas de secrets trouvés dans le code source versionné
|
||
|
|
- CI/CD utilise GitHub Secrets
|
||
|
|
- Backend masque les secrets dans les logs (`config.go:1369-1384`)
|
||
|
|
|
||
|
|
### Reproductibilité
|
||
|
|
|
||
|
|
Le setup est reproductible via Docker Compose. `fixtures/` package permet le seeding. Pas de `docker-compose up` one-liner documenté qui lance tout le stack — chaque service a son propre compose.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. RISQUES BUSINESS
|
||
|
|
|
||
|
|
### Point de vue CTO
|
||
|
|
|
||
|
|
**Peut-on lancer ce produit en prod ?**
|
||
|
|
|
||
|
|
**Non, pas en l'état.** Les 3 vulnérabilités critiques (bypass rate limiting via headers, bypass CSRF en dev, bypass rôles en dev) doivent être corrigées avant tout déploiement. Le pipeline d'encodage audio est un stub. 4 features sont désactivées par feature flag côté frontend alors que le backend est prêt. Le code mort (Studio, 93+ fichiers) alourdit inutilement la base de code.
|
||
|
|
|
||
|
|
**Temps estimé pour atteindre le production-ready :** 3-4 semaines avec 2 développeurs seniors.
|
||
|
|
|
||
|
|
### Point de vue investisseur
|
||
|
|
|
||
|
|
**Peut-on investir dans ce produit ?**
|
||
|
|
|
||
|
|
**Oui, avec réserves.** Le socle technique est solide : stack moderne, architecture microservices, 150+ endpoints fonctionnels, auth mature, monitoring intégré. Le produit couvre un large périmètre fonctionnel (audio, marketplace, social, chat, analytics). La dette technique est significative mais traitable. Les vulnérabilités sont corrigeables rapidement.
|
||
|
|
|
||
|
|
**Risques principaux :**
|
||
|
|
1. Un seul développeur apparent (volume de code vs qualité homogène)
|
||
|
|
2. Feature scope très ambitieux pour une phase pré-production
|
||
|
|
3. Services Rust avec des TODOs critiques non résolus
|
||
|
|
|
||
|
|
### Point de vue acquéreur
|
||
|
|
|
||
|
|
**Peut-on acheter ce produit ?**
|
||
|
|
|
||
|
|
**Avec décote.** La valeur réside dans :
|
||
|
|
- L'architecture globale (Go + Rust + React, scalable)
|
||
|
|
- Le backend API mature (150+ endpoints, 92% coverage revendiqué)
|
||
|
|
- Le frontend riche (799 composants, i18n, a11y)
|
||
|
|
|
||
|
|
**Facteurs de décote :**
|
||
|
|
- ~150 fichiers de code mort à nettoyer
|
||
|
|
- Services Rust pas production-ready
|
||
|
|
- 3 vulnérabilités critiques
|
||
|
|
- Pas de revenus ni d'utilisateurs documentés
|
||
|
|
- Monorepo sans orchestration
|
||
|
|
|
||
|
|
**Faut-il refactorer ou réécrire ?**
|
||
|
|
|
||
|
|
**Refactorer.** La base est saine. Les problèmes sont des problèmes de nettoyage, pas de conception fondamentale. Le coût de réécriture serait prohibitif par rapport au coût de remédiation (~3-4 semaines vs ~6-12 mois).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. PLAN D'ACTION PRIORISÉ
|
||
|
|
|
||
|
|
### Phase 1 — Urgent (sécurité & stabilité) — 1-2 semaines
|
||
|
|
|
||
|
|
| Action | Effort | Fichier(s) | Détail |
|
||
|
|
|--------|--------|-----------|--------|
|
||
|
|
| Supprimer le bypass rate limiting via headers | S | `rate_limiter.go:94-104` | Retirer la vérification `X-Test-Mode` et `X-E2E-Test`. Utiliser uniquement les variables d'environnement. |
|
||
|
|
| Supprimer le bypass CSRF en dev | S | `csrf.go:44-47` | Retirer le bypass ou le gater derrière un flag explicite `CSRF_DISABLED=true` (jamais activé en prod). |
|
||
|
|
| Supprimer le bypass rôle en dev | S | `auth.go:440-451` | Idem, flag explicite ou suppression. |
|
||
|
|
| Corriger la comparaison CSRF timing-safe | S | `csrf.go:122` | Remplacer `!=` par `crypto/subtle.ConstantTimeCompare()`. |
|
||
|
|
| Supprimer le debug print | S | `auth.go:88` | Retirer `fmt.Println("DEBUG: ...")`. |
|
||
|
|
| Corriger les numéros de migration dupliqués | S | `020_*.sql`, `050_*.sql` | Renommer `020_rbac_and_profiles.sql` → `021_rbac_and_profiles.sql`, `050_legacy_chat.sql` → `051_legacy_chat.sql`. |
|
||
|
|
| Rendre `INTERNAL_API_KEY` obligatoire | S | `compression.rs:536` | Fail si non défini au lieu de warning. |
|
||
|
|
| Implémenter fail-secure pour account lockout | M | `account_lockout_service.go:89-94` | Fallback in-memory au lieu de fail-open quand Redis est down. |
|
||
|
|
| Implémenter fail-secure pour rate limiting chat | M | `handler.rs:299` | Idem, fallback in-memory. |
|
||
|
|
| Rejeter les mots de passe > 72 bytes | S | `password_service.go:299-303` | Retourner une erreur au lieu de tronquer silencieusement. |
|
||
|
|
| Ajouter Trivy au CD principal | M | `.github/workflows/cd.yml` | Scan avant push d'images. |
|
||
|
|
|
||
|
|
### Phase 2 — Stabilisation — 2-4 semaines
|
||
|
|
|
||
|
|
| Action | Effort | Fichier(s) | Détail |
|
||
|
|
|--------|--------|-----------|--------|
|
||
|
|
| Supprimer le code Studio mort | L | `components/studio/` (93+ fichiers) | Supprimer ou déplacer dans une branche feature. |
|
||
|
|
| Supprimer les services mock-only | M | `gamificationService.ts`, `projectService.ts`, `storageService.ts` | Supprimer ou déplacer. |
|
||
|
|
| Migrer Modal → Dialog | M | Tous les imports de `modal.tsx` | Remplacer par `Dialog` partout. |
|
||
|
|
| Activer les feature flags prêts | M | `config/features.ts` | Activer `HLS_STREAMING`, `PLAYLIST_SEARCH`, `ROLE_MANAGEMENT`, `PLAYLIST_RECOMMENDATIONS`. |
|
||
|
|
| Implémenter les composants manquants ou supprimer les tests | L | 19 fichiers exclus de vitest | Soit implémenter, soit nettoyer les tests orphelins. |
|
||
|
|
| Fixer les 7 tests skippés | M | Suites Vitest | Corriger les tests ou les supprimer si obsolètes. |
|
||
|
|
| Ajouter les migrations down | L | `migrations/` | Écrire les scripts de rollback pour chaque migration. |
|
||
|
|
| Découper `router.go` | M | `router.go` (1576 lignes) | Séparer en sous-fichiers par domaine (auth, tracks, playlists, etc.). |
|
||
|
|
| Compléter le repository pattern | M | `internal/repositories/` | Créer les repositories manquants (Track, Notification, Webhook, Role). |
|
||
|
|
| Nettoyer les modules Rust legacy | S | `security_legacy.rs`, `auth.rs` | Supprimer si inutilisés. |
|
||
|
|
| Résoudre les 100+ TODOs frontend | L | Frontend entier | Prioriser et traiter ou supprimer. |
|
||
|
|
|
||
|
|
### Phase 3 — Amélioration & refonte — 4-8 semaines
|
||
|
|
|
||
|
|
| Action | Effort | Fichier(s) | Détail |
|
||
|
|
|--------|--------|-----------|--------|
|
||
|
|
| Implémenter le pipeline d'encodage réel | XL | `encoding_pool.rs` | Remplacer le stub par un vrai pipeline FFmpeg/GStreamer. |
|
||
|
|
| Ajouter `go.work` ou un orchestrateur monorepo | L | Racine | Turborepo ou Nx pour orchestrer Go + Rust + React. |
|
||
|
|
| Remplacer `go-clamd` | M | `go.mod` | Fork ou alternative maintenue pour ClamAV. |
|
||
|
|
| Ajouter la signature d'images Docker | M | CD pipeline | Intégrer cosign dans le workflow de déploiement. |
|
||
|
|
| Générer des SBOM | M | CD pipeline | Supply chain security. |
|
||
|
|
| Filtrage SSRF sur les webhooks | M | `webhook.go` | Bloquer les URLs internes/privées dans les webhooks utilisateur. |
|
||
|
|
| Configurer les timeouts Rust | S | Chat/Stream servers | Rendre configurables via env les timeouts hardcodés. |
|
||
|
|
| Ajouter un distributed lock pour session refresh | M | `auth.go:199-216` | Redis lock pour éviter les race conditions. |
|
||
|
|
| Optimiser `GetTrackStats()` | S | Track service | 4 requêtes → 1 requête avec jointures. |
|
||
|
|
| Audit de composants > 300 lignes | M | Frontend | Découper selon les règles projet. |
|
||
|
|
| Ajouter des indexes manquants | S | Migrations | `tracks.file_id`, `tracks.cover_art_file_id`, `messages.attachment_file_id`. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## CONCLUSION STRATÉGIQUE
|
||
|
|
|
||
|
|
Le monorepo Veza représente un **effort de développement considérable et architecturalement cohérent**. Le choix de Go pour l'API, Rust pour les services temps réel, et React pour le frontend est pertinent pour une plateforme audio collaborative.
|
||
|
|
|
||
|
|
**Le produit n'est pas un prototype** — c'est une application fonctionnelle avec 150+ endpoints, 20+ features, une sécurité raisonnablement mature, et une infrastructure Docker/Kubernetes prête.
|
||
|
|
|
||
|
|
**Cependant, le produit n'est pas production-ready.** Trois vulnérabilités critiques exploitables par un attaquant non sophistiqué (simples headers HTTP ou misconfiguration d'environnement) doivent être corrigées en priorité absolue. Le pipeline d'encodage audio — qui est au coeur du produit — est un stub.
|
||
|
|
|
||
|
|
**La dette technique est significative mais pas structurelle.** Elle relève principalement de code mort (Studio fantôme), de features inachevées (gamification, encoding), et de bypasses de développement laissés actifs. Le coût de remédiation est estimé à 3-4 semaines pour la phase 1, 2-4 semaines pour la phase 2.
|
||
|
|
|
||
|
|
**Recommandation finale :** Investissement viable sous condition de remédiation des vulnérabilités critiques (Phase 1) avant tout déploiement utilisateur. Le socle technique justifie un refactoring plutôt qu'une réécriture.
|