veza/docs/ASVS_CHECKLIST_v0.12.6.md

250 lines
14 KiB
Markdown
Raw Normal View History

# OWASP ASVS Level 2 Checklist — VEZA v0.12.6
**Date** : 2026-03-13
**Standard** : OWASP Application Security Verification Standard v4.0.3, Level 2
**Scope** : VEZA monorepo (Go backend, Rust stream server, React frontend)
**Référence** : PENTEST_REPORT_VEZA_v0.12.6.md (36 findings)
---
## Légende
- ✅ PASS — Contrôle vérifié et conforme
- ⚠️ PARTIAL — Contrôle partiellement implémenté (finding associé)
- ❌ FAIL — Contrôle non conforme (finding associé)
- N/A — Non applicable
---
## V1 — Architecture, Design and Threat Modeling
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V1.1.1 | Application uses a single vetted security architecture | ✅ PASS | Architecture hexagonale, middlewares auth centralisés |
| V1.1.2 | Security controls are applied centrally | ✅ PASS | Auth middleware, rate limit middleware, CORS config centralisée |
| V1.1.3 | Sensitive data is identified and protected | ⚠️ PARTIAL | `json:"-"` sur passwords/tokens, mais popularity metrics leakent — **HIGH-002** |
| V1.1.4 | All application components are defined | ✅ PASS | ORIGIN_MASTER_ARCHITECTURE.md documente tous les composants |
| V1.1.5 | High-value business logic flows defined | ⚠️ PARTIAL | Flows définis mais race conditions dans payout/refund — **CRIT-002, CRIT-003** |
| V1.1.6 | Threat model exists | ⚠️ PARTIAL | ORIGIN_SECURITY_FRAMEWORK.md existe mais pas de threat model formel |
---
## V2 — Authentication
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V2.1.1 | Password min length ≥ 8 | ✅ PASS | Validation de complexité dans password_service.go |
| V2.1.2 | Password max length ≥ 64 | ✅ PASS | Max 72 bytes (bcrypt limit) enforced |
| V2.1.3 | No password truncation | ✅ PASS | Validation explicite de la longueur avant hachage |
| V2.1.4 | Passwords are stored using approved hashing | ⚠️ PARTIAL | bcrypt utilisé mais cost incohérent (10 vs 12) — **MEDIUM-001** |
| V2.1.5 | Password change requires old password | ✅ PASS | `ChangePassword()` vérifie l'ancien mot de passe |
| V2.1.6 | Password breach checking | ✅ PASS | Password history (5 derniers) vérifié |
| V2.2.1 | Anti-automation controls on auth | ⚠️ PARTIAL | Rate limiting existe mais bypassable via IP spoofing — **HIGH-001** |
| V2.2.2 | Weak authenticator resistance | ✅ PASS | Brute-force protection via rate limiting + account lockout |
| V2.2.3 | Credential recovery resists abuse | ✅ PASS | Password reset tokens limités, expirent |
| V2.3.1 | Session tokens are generated using approved CSPRNG | ✅ PASS | crypto/rand utilisé (19 fichiers) |
| V2.4.1 | MFA available | ✅ PASS | TOTP MFA + recovery codes implémentés |
| V2.5.1 | Tokens not sent as query parameters | ✅ PASS | JWT via cookies HttpOnly |
| V2.5.2 | Token integrity is checked | ✅ PASS | JWT RS256 signature verification |
| V2.5.3 | Stateless tokens include expiry | ✅ PASS | JWT `exp` claim enforced |
| V2.5.4 | JWT algorithm whitelisting | ✅ PASS | RS256 primary, HS256 dev-only fallback |
| V2.7.1 | Passwords are hashed with salt | ✅ PASS | bcrypt inclut le salt automatiquement |
| V2.8.1 | Session management for auth tokens | ⚠️ PARTIAL | Session service avec revocation, mais refresh token TOCTOU — **HIGH-005** |
| V2.9.1 | WebAuthn support | ✅ PASS | WebAuthn credentials stored securely (`json:"-"`) |
---
## V3 — Session Management
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V3.1.1 | Application never reveals session tokens in URL | ✅ PASS | Cookies HttpOnly uniquement |
| V3.2.1 | Logout invalidates session | ✅ PASS | Token blacklist + session deletion |
| V3.2.2 | Logout invalidates all sessions option | ✅ PASS | "Revoke all sessions" available |
| V3.2.3 | Session timeout after inactivity | ✅ PASS | Token expiration configured |
| V3.3.1 | Session token is changed after login | ✅ PASS | New JWT issued on each login |
| V3.4.1 | Cookie-based tokens have Secure flag | ✅ PASS | Auto-secure in production (cors.go:12-18) |
| V3.4.2 | Cookie-based tokens have HttpOnly flag | ✅ PASS | `CookieHttpOnly: true` |
| V3.4.3 | Cookie-based tokens have SameSite attribute | ⚠️ PARTIAL | SameSite=Lax (Strict préférable) — **LOW-001** |
| V3.4.4 | Cookie-based tokens use __Host- prefix | N/A | Non requis pour Level 2 |
| V3.5.1 | Tokens are validated on every request | ✅ PASS | Auth middleware validates JWT on protected routes |
| V3.7.1 | Admin can revoke user sessions | ✅ PASS | Admin session management available |
---
## V4 — Access Control
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V4.1.1 | Principle of least privilege | ⚠️ PARTIAL | Roles définis mais mass assignment permet escalation — **HIGH-003** |
| V4.1.2 | Access control applied server-side | ✅ PASS | All auth checks in Go middleware/handlers |
| V4.1.3 | Deny by default | ✅ PASS | Protected routes require explicit auth middleware |
| V4.2.1 | Sensitive data access restricted | ❌ FAIL | Analytics IDOR (pas de ownership check) — **CRIT-004** ; followers_count public — **HIGH-002** |
| V4.2.2 | User can only access own data | ❌ FAIL | Track analytics de n'importe quel créateur accessible — **CRIT-004** |
| V4.3.1 | Admin functions protected | ✅ PASS | `RequireRole("admin")` middleware |
| V4.3.2 | Users cannot access unauthorized admin APIs | ✅ PASS | Role check in middleware before handler |
---
## V5 — Validation, Sanitization and Encoding
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V5.1.1 | HTTP parameter pollution defense | ✅ PASS | Gin framework handles this natively |
| V5.1.2 | Input validation on all inputs | ⚠️ PARTIAL | Struct binding OK mais file upload marketplace sans validation taille — **MEDIUM-006** |
| V5.1.3 | Output encoding for context | ✅ PASS | React auto-escapes, Go JSON marshaling |
| V5.2.1 | Untrusted HTML sanitized | ✅ PASS | DOMPurify (frontend) + `html.EscapeString` (backend) |
| V5.3.1 | SQL injection prevention | ✅ PASS | Parameterized queries everywhere |
| V5.3.2 | OS command injection prevention | ✅ PASS | `exec.CommandContext` avec arguments séparés |
| V5.3.3 | LDAP injection prevention | N/A | No LDAP used |
| V5.3.4 | XSS prevention | ✅ PASS | React JSX auto-escaping, CSP header |
| V5.3.7 | SSRF prevention | ✅ PASS | No user-controlled URL fetching in backend |
| V5.5.1 | Serialization attacks prevented | ✅ PASS | No deserialization of untrusted data |
---
## V6 — Stored Cryptography
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V6.1.1 | Regulated data encrypted at rest | ✅ PASS | Passwords bcrypt-hashed, tokens hashed |
| V6.2.1 | Approved cryptographic algorithms | ✅ PASS | bcrypt, RS256, HMAC-SHA512, crypto/rand |
| V6.2.2 | Industry-proven crypto libraries | ✅ PASS | Go stdlib crypto, `golang.org/x/crypto` |
| V6.2.3 | Random values from CSPRNG | ✅ PASS | `crypto/rand` exclusively (not math/rand) |
| V6.2.4 | Key rotation supported | ⚠️ PARTIAL | JWT key rotation documentée mais pas de `kid` header — **INFO-003** |
| V6.3.1 | Secrets not in source code | ⚠️ PARTIAL | `.env.production` uses templates, mais JWT_SECRET hardcodé dans docker-compose — **LOW-006** |
| V6.4.1 | Key management procedures | ✅ PASS | JWT RSA keys loaded from env/files |
---
## V7 — Error Handling and Logging
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V7.1.1 | Generic error messages to users | ✅ PASS | apierror package with structured errors, no stack traces |
| V7.1.2 | Security-sensitive errors logged | ✅ PASS | Structured JSON logging with zap |
| V7.1.3 | No sensitive data in error responses | ✅ PASS | Error context sanitized |
| V7.2.1 | All auth decisions logged | ✅ PASS | Login success/failure, session revocation logged |
| V7.2.2 | All access control failures logged | ✅ PASS | 401/403 responses logged |
| V7.3.1 | Logs protected from injection | ✅ PASS | Structured logging (zap) prevents log injection |
| V7.4.1 | Sensitive data not logged | ✅ PASS | Passwords, tokens not in log fields |
---
## V8 — Data Protection
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V8.1.1 | PII identified and classified | ✅ PASS | PRIVACY_POLICY.md §2 lists all data |
| V8.1.2 | Sensitive data in transit encrypted | ✅ PASS | HTTPS/TLS enforced, HSTS header |
| V8.2.1 | Sensitive data not in URL | ✅ PASS | Auth via cookies, not URL params |
| V8.2.2 | HTTP caching headers on sensitive data | ✅ PASS | Cache-Control set on auth responses |
| V8.3.1 | Sensitive data removable on request | ⚠️ PARTIAL | GDPR deletion fonctionne mais données financières non traitées — **HIGH-008** |
| V8.3.2 | Data export available | ✅ PASS | GDPR export endpoint (JSON, 48h) |
| V8.3.4 | Data retention policy defined | ✅ PASS | PRIVACY_POLICY.md §7 — retention table |
---
## V9 — Communication
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V9.1.1 | TLS for all connections | ⚠️ PARTIAL | HTTPS enforced, HSTS backend, mais nginx frontend manque HSTS — **MEDIUM-009** |
| V9.1.2 | TLS 1.2+ only | ✅ PASS | Go net/http defaults to TLS 1.2+ |
| V9.1.3 | Strong cipher suites | ✅ PASS | Go stdlib uses modern ciphers |
| V9.2.1 | Webhook signature verification | ✅ PASS | HMAC-SHA512 with hmac.Equal() |
---
## V10 — Malicious Code
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V10.1.1 | No malicious code (backdoors, etc.) | ✅ PASS | No suspicious patterns found |
| V10.2.1 | No time bombs | ✅ PASS | No scheduled destructive operations |
| V10.3.1 | Source code review performed | ✅ PASS | This audit (6 agents spécialisés) |
---
## V11 — Business Logic
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V11.1.1 | Business logic flow enforced server-side | ❌ FAIL | Race conditions dans payout, refund, promo, trial — **CRIT-002, CRIT-003, HIGH-006, HIGH-010** |
| V11.1.2 | Business logic limits enforced | ⚠️ PARTIAL | Rate limits existent mais pagination unbounded — **MEDIUM-005** |
| V11.1.3 | Anti-automation on business-critical functions | ⚠️ PARTIAL | Rate limiting bypassable via IP spoofing — **HIGH-001** |
| V11.1.4 | Ethical business logic verified | ⚠️ PARTIAL | Track metrics hidden, mais API leaks followers/post likes — **HIGH-002** |
---
## V12 — Files and Resources
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V12.1.1 | File upload size limits | ⚠️ PARTIAL | Upload validation service OK, mais marketplace upload manque check taille — **MEDIUM-006** |
| V12.1.2 | File type validation | ✅ PASS | `ValidateFile()` checks file types |
| V12.1.3 | File stored outside webroot | ✅ PASS | MinIO/S3 object storage |
| V12.3.1 | User-submitted filenames sanitized | ❌ FAIL | Marketplace upload : path traversal via `filepath.Join`**CRIT-005** |
| V12.4.1 | No path traversal | ❌ FAIL | `filepath.Join(previewDir, file.Filename)` sans sanitization — **CRIT-005** |
---
## V13 — API and Web Service
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V13.1.1 | All API endpoints require auth or are explicitly public | ⚠️ PARTIAL | Endpoints protégés, mais pprof exposé sans restriction — **MEDIUM-012** |
| V13.1.2 | API uses standard auth mechanisms | ✅ PASS | JWT bearer tokens |
| V13.1.3 | No unnecessary API exposure | ⚠️ PARTIAL | pprof profiling endpoint exposé — **MEDIUM-012** |
| V13.2.1 | Rate limiting on all APIs | ⚠️ PARTIAL | Rate limit bypassable via IP spoofing — **HIGH-001** |
| V13.2.2 | API schema validation | ✅ PASS | Gin binding validation |
| V13.3.1 | Pagination implemented | ⚠️ PARTIAL | Pagination existe mais limit non borné — **MEDIUM-005** |
| V13.4.1 | CORS properly configured | ⚠️ PARTIAL | HTTP origins in .env.production — **MEDIUM-003** ; Nginx RTMP wildcard — **MEDIUM-007** |
---
## V14 — Configuration
| # | Contrôle | Statut | Notes |
|---|----------|--------|-------|
| V14.1.1 | Server configuration hardened | ⚠️ PARTIAL | Security headers backend OK, mais nginx frontend manque HSTS — **MEDIUM-009** |
| V14.2.1 | Dependency integrity | ⚠️ PARTIAL | GitHub Actions not all pinned by SHA — **MEDIUM-002** |
| V14.2.2 | No known vulnerabilities in dependencies | ✅ PASS | Trivy scans in CI, cargo audit, npm audit |
| V14.3.1 | Security headers set | ✅ PASS | HSTS, CSP, COEP, COOP (backend) |
| V14.4.1 | No default credentials | ⚠️ PARTIAL | `.env.production` uses templates, mais JWT_SECRET hardcodé en dev — **LOW-006** |
| V14.5.1 | HTTP security headers | ✅ PASS | X-Content-Type-Options, Referrer-Policy |
---
## Résumé ASVS
| Catégorie | Total | ✅ PASS | ⚠️ PARTIAL | ❌ FAIL | N/A |
|-----------|-------|---------|------------|--------|--------|
| V1 Architecture | 6 | 3 | 3 | 0 | 0 |
| V2 Authentication | 18 | 14 | 4 | 0 | 0 |
| V3 Session Mgmt | 11 | 10 | 1 | 0 | 0 |
| V4 Access Control | 7 | 4 | 1 | 2 | 0 |
| V5 Validation | 10 | 8 | 1 | 0 | 1 |
| V6 Cryptography | 7 | 5 | 2 | 0 | 0 |
| V7 Error Handling | 7 | 7 | 0 | 0 | 0 |
| V8 Data Protection | 7 | 6 | 1 | 0 | 0 |
| V9 Communication | 4 | 3 | 1 | 0 | 0 |
| V10 Malicious Code | 3 | 3 | 0 | 0 | 0 |
| V11 Business Logic | 4 | 0 | 3 | 1 | 0 |
| V12 Files | 5 | 2 | 1 | 2 | 0 |
| V13 API | 7 | 2 | 5 | 0 | 0 |
| V14 Configuration | 6 | 3 | 3 | 0 | 0 |
| **Total** | **102** | **70** | **26** | **5** | **1** |
**Taux de conformité ASVS Level 2** : **70/102 (68.6%)**
- 5 contrôles ❌ FAIL sont associés à des findings CRITICAL (CRIT-002/003/004/005, HIGH-003)
- 26 contrôles ⚠️ PARTIAL sont associés à des findings HIGH/MEDIUM/LOW documentés
- Tous les findings ont des remédiations concrètes dans la REMEDIATION_MATRIX
**Objectif v1.0.0** : Résoudre tous les FAIL et réduire les PARTIAL pour atteindre ≥ 85% conformité.
---
*Checklist ASVS générée le 2026-03-13 — VEZA v0.12.6 — Audit complet (36 findings)*