veza/veza-common/AUDIT_REPORT.md
2025-12-12 21:34:34 -05:00

506 lines
17 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AUDIT TECHNIQUE EXHAUSTIF — veza-common
**Date**: 2024-12-19
**Module**: `veza-common` (Bibliothèque Rust partagée)
**Auditeur**: Auto (Cursor AI)
**Version analysée**: 0.1.0
---
## PHASE A — CARTOGRAPHIE
### Module Overview
**Rôle**: Bibliothèque commune Rust fournissant types partagés, utilitaires, configurations, gestion d'erreurs, authentification, logging et métriques pour tous les services Veza (backend Go, chat-server Rust, stream-server Rust).
**Entrées/Sorties**:
- **Pas d'API HTTP/WS directe** (bibliothèque uniquement)
- **Types sérialisables** (JSON via serde) pour communication inter-services
- **Traits async** pour abstraction des providers (Auth, Cache, DB, Stream, etc.)
- **Erreurs standardisées** (`CommonError`, `VezaError`) avec codes HTTP
- **Configurations** (Database, Redis, JWT, Server, RateLimit, Logging)
**Dépendances internes**:
- Aucune (module racine du monorepo)
**Dépendances externes**:
- **DB**: PostgreSQL via `sqlx` (runtime-tokio-rustls)
- **Cache**: Redis (config uniquement, pas d'implémentation)
- **Auth**: JWT (structures, pas d'implémentation complète)
- **Crypto**: `sha2`, `hmac`, `base64`
- **Async**: `tokio` (full features)
- **Logging**: `tracing`, `tracing-subscriber`
- **Metrics**: `prometheus`
- **Serialization**: `serde`, `serde_json`
- **Validation**: `validator`, `regex`
**Exécution**:
```bash
# Build
cargo build --release
# Tests
cargo test
# Documentation
cargo doc --open
```
**Configuration**:
- Variables d'environnement (via `VezaConfig` trait)
- Fichiers JSON (optionnel)
- Defaults hardcodés (⚠️ secrets exposés)
**Points d'intégration**:
- **Types UUID** (v4) pour tous les IDs
- **JWT claims** avec `sub`, `iss`, `aud`, `exp`, `iat`, `nbf`, `jti`
- **Erreurs HTTP** standardisées (400, 401, 403, 404, 409, 429, 500)
- **Logging structuré** (tracing avec JSON/text)
- **Métriques Prometheus** (counters, gauges, histograms)
### Runbook Minimal
```bash
# 1. Vérifier dépendances
cd veza-common
cargo check
# 2. Lancer tests
cargo test --verbose
# 3. Build release
cargo build --release
# 4. Générer docs
cargo doc --no-deps --open
```
---
## PHASE B — SANTÉ TECHNIQUE
### Build Status
**❌ BUILD CASSÉ** — 9 erreurs de compilation identifiées:
1. **Module `serialization` manquant** (`src/utils/serialization.rs` n'existe pas)
2. **Module `logging` manquant** (`src/utils/logging.rs` n'existe pas, mais `src/logging.rs` existe)
3. **Dépendance `rand` manquante** (utilisée dans `auth.rs`, `random.rs`)
4. **Dépendance `totp_rs` manquante** (utilisée dans `auth.rs`)
5. **Feature `env-filter` manquante** pour `tracing-subscriber`
6. **Imports incorrects** (`VezaError`, `VezaResult` non exportés au root, utilisés dans `auth.rs`, `logging.rs`, `metrics.rs`, `traits.rs`, `config_rust.rs`)
### Linter Status
**⚠️ CLIPPY NON INSTALLÉ** — Impossible d'exécuter `cargo clippy`
### Tests Status
**✅ Tests présents** — `tests/common_tests.rs` avec 15+ tests unitaires
- Couverture: ~60% estimée (pas de métrique exacte)
- Tests manquants: modules `auth`, `metrics`, `traits`, `config_rust`
### Gestion des Erreurs
**⚠️ PROBLÈMES IDENTIFIÉS**:
- **27 occurrences de `unwrap()`/`expect()`/`panic!`** dans le code
- **Comparaison HMAC non constante** (timing attack possible)
- **Erreurs non wrappées** dans certains cas
### Conventions
**✅ Cohérent**:
- Naming: snake_case pour fonctions, PascalCase pour types
- Structure: modules organisés (`types/`, `utils/`, `config/`, `error/`)
- Séparation: traits vs implémentations
**⚠️ Incohérences**:
- Deux systèmes d'erreurs (`CommonError` vs `VezaError`)
- Deux systèmes de config (`config/` vs `config_rust.rs`)
---
## PHASE C — SÉCURITÉ
### Top 10 Risques
#### P0 — CRITIQUES
**MOD-P0-001: Secrets hardcodés dans code source**
- **Fichier**: `src/config_rust.rs:234`, `src/config_rust.rs:46`
- **Impact**: Secrets JWT et DB exposés dans le code, compromission complète de l'auth
- **Preuve**:
```rust
// src/config_rust.rs:234
secret: "your-super-secret-jwt-key".to_string(),
// src/config_rust.rs:46
url: "postgresql://veza:password@localhost:5432/veza_db".to_string(),
```
- **Cause**: Defaults hardcodés au lieu de fail-fast si env var manquante
- **Fix**: Supprimer defaults secrets, exiger variables d'environnement
- **Validation**: `cargo test` + scan secrets (git-secrets, truffleHog)
- **Régression**: Risque faible (tests doivent échouer si secrets manquants)
- **Effort**: S (1h)
**MOD-P0-002: Comparaison HMAC vulnérable aux attaques de timing**
- **Fichier**: `src/utils/crypto.rs:26-28`
- **Impact**: Attaque par canal auxiliaire permettant de forger des signatures
- **Preuve**:
```rust
pub fn verify_hmac_signature(data: &str, signature: &str, secret: &str) -> Result<bool> {
let expected = generate_hmac_signature(data, secret)?;
Ok(signature == expected) // ⚠️ Comparaison non constante
}
```
- **Cause**: Utilisation de `==` sur `String` au lieu de comparaison constante
- **Fix**: Utiliser `constant_time_eq` ou `subtle::ConstantTimeEq`
- **Validation**: Test unitaire avec timing attack simulé
- **Régression**: Risque faible (comportement fonctionnel identique)
- **Effort**: S (30min)
**MOD-P0-003: Variables globales non thread-safe**
- **Fichier**: `src/metrics.rs:215`
- **Impact**: Data race, corruption mémoire, crash en production
- **Preuve**:
```rust
pub static mut GLOBAL_METRICS: Option<Arc<MetricsCollector>> = None;
```
- **Cause**: Utilisation de `static mut` au lieu de `OnceCell`/`LazyLock`
- **Fix**: Remplacer par `std::sync::OnceLock` ou `lazy_static::lazy_static!`
- **Validation**: Test de concurrence avec `loom` ou `std::thread`
- **Régression**: Risque moyen (changement d'API)
- **Effort**: M (2h)
#### P1 — HAUTE PRIORITÉ
**MOD-P1-004: Dépendances manquantes (rand, totp_rs)**
- **Fichier**: `Cargo.toml`, `src/auth.rs:293`, `src/utils/random.rs:24`
- **Impact**: Build cassé, fonctionnalités inutilisables
- **Preuve**: Erreurs de compilation `unresolved import 'rand'`
- **Cause**: Dépendances utilisées mais non déclarées
- **Fix**: Ajouter `rand = "0.8"` et `totp_rs = "2.0"` dans `Cargo.toml`
- **Validation**: `cargo check` doit passer
- **Régression**: Aucune
- **Effort**: S (15min)
**MOD-P1-005: Modules manquants (serialization, logging dans utils)**
- **Fichier**: `src/utils/mod.rs:6,8`
- **Impact**: Build cassé
- **Preuve**: Erreur `file not found for module 'serialization'`
- **Cause**: Modules déclarés mais fichiers absents
- **Fix**: Créer fichiers ou supprimer déclarations (logging existe au root)
- **Validation**: `cargo check`
- **Régression**: Aucune
- **Effort**: S (30min)
**MOD-P1-006: Exports manquants (VezaError, VezaResult)**
- **Fichier**: `src/lib.rs`, `src/auth.rs:9`, `src/logging.rs:13`, etc.
- **Impact**: Build cassé, imports incorrects
- **Preuve**: Erreurs `unresolved imports 'crate::VezaError'`
- **Cause**: Types non exportés au root alors qu'utilisés partout
- **Fix**: Ajouter `pub use error::server::{VezaError, VezaResult};` dans `lib.rs`
- **Validation**: `cargo check`
- **Régression**: Aucune
- **Effort**: S (15min)
**MOD-P1-007: Feature flag manquant (env-filter)**
- **Fichier**: `Cargo.toml`, `src/logging.rs:10`
- **Impact**: Build cassé
- **Preuve**: Erreur `no 'EnvFilter' in the root`
- **Cause**: Feature `env-filter` non activée pour `tracing-subscriber`
- **Fix**: Ajouter `features = ["env-filter"]` à `tracing-subscriber` dans `Cargo.toml`
- **Validation**: `cargo check`
- **Régression**: Aucune
- **Effort**: S (5min)
**MOD-P1-008: Validation JWT secret trop faible**
- **Fichier**: `src/config_rust.rs:269`
- **Impact**: Secrets faibles acceptés, compromission possible
- **Preuve**:
```rust
if self.secret.len() < 32 {
warn!("JWT secret is shorter than recommended 32 characters");
}
```
- **Cause**: Warning seulement, pas d'erreur
- **Fix**: Rejeter secrets < 32 caractères en production (ou 64 recommandé)
- **Validation**: Test avec secret court doit échouer
- **Régression**: Risque faible (validation plus stricte)
- **Effort**: S (30min)
#### P2 — MOYENNE PRIORITÉ
**MOD-P2-009: Regex compilées à chaque appel**
- **Fichier**: `src/utils/validation.rs:7,20`
- **Impact**: Performance dégradée, allocations inutiles
- **Preuve**:
```rust
let email_regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
.expect("Invalid email regex");
```
- **Cause**: Pas de `lazy_static` ou `once_cell`
- **Fix**: Utiliser `lazy_static::lazy_static!` ou `std::sync::LazyLock`
- **Validation**: Benchmark avant/après
- **Régression**: Aucune
- **Effort**: S (30min)
**MOD-P2-010: Utilisation excessive de unwrap()**
- **Fichier**: Multiple (27 occurrences)
- **Impact**: Panics en production, crashs
- **Preuve**: Voir grep results
- **Cause**: Pas de gestion d'erreur appropriée
- **Fix**: Remplacer par `?` ou gestion explicite
- **Validation**: Tests avec cas limites
- **Régression**: Risque moyen (changement de comportement)
- **Effort**: M (4h)
### Autres Risques Sécurité
- **MOD-P2-011**: Pas de validation de force de secret JWT (entropie)
- **MOD-P2-012**: Pas de rate limiting sur génération de tokens
- **MOD-P2-013**: Pas de rotation automatique de secrets
- **MOD-P3-014**: Logs peuvent contenir des secrets (pas de sanitization)
---
## PHASE D — ROBUSTESSE & OBSERVABILITÉ
### Production Readiness Gaps
#### P0 — BLOQUANTS
**MOD-P0-015: Build cassé**
- **Impact**: Impossible de déployer
- **Fix**: Résoudre toutes les erreurs de compilation (MOD-P1-004 à MOD-P1-007)
- **Effort**: M (2h)
#### P1 — CRITIQUES
**MOD-P1-016: Pas de healthcheck endpoint**
- **Impact**: Impossible de monitorer la santé du service
- **Fix**: Ajouter trait `HealthCheck` avec implémentation
- **Effort**: M (2h)
**MOD-P1-017: Logs non structurés dans certains cas**
- **Impact**: Difficulté d'analyse en production
- **Preuve**: `src/utils/validation.rs` utilise `expect()` sans contexte
- **Fix**: Utiliser `tracing::error!` avec contexte
- **Effort**: M (3h)
**MOD-P1-018: Pas de corrélation de requêtes (request_id)**
- **Impact**: Impossible de tracer une requête à travers les logs
- **Fix**: Ajouter `request_id` dans tous les logs
- **Effort**: M (4h)
**MOD-P1-019: Pas de métriques de performance**
- **Impact**: Pas de visibilité sur les performances
- **Preuve**: `MetricsCollector` existe mais pas d'utilisation automatique
- **Fix**: Intégrer métriques dans tous les traits
- **Effort**: L (8h)
#### P2 — IMPORTANTS
**MOD-P2-020: Pas de retry automatique dans traits**
- **Impact**: Échecs transitoires non gérés
- **Fix**: Ajouter retry dans implémentations
- **Effort**: M (4h)
**MOD-P2-021: Pas de timeout par défaut**
- **Impact**: Opérations peuvent bloquer indéfiniment
- **Fix**: Ajouter timeouts dans tous les traits async
- **Effort**: M (3h)
**MOD-P2-022: Pas de circuit breaker**
- **Impact**: Cascading failures possibles
- **Fix**: Ajouter circuit breaker dans traits
- **Effort**: L (6h)
---
## PHASE E — PERFORMANCE & SCALABILITÉ
### Optimisations Mesurables
1. **MOD-P2-009**: Regex compilées (gain estimé: 50-100ns par appel)
2. **MOD-P2-023**: Pool de connexions DB non configuré (gain: réduction latence 10-50ms)
3. **MOD-P2-024**: Pas de cache pour métriques (gain: réduction allocations)
4. **MOD-P2-025**: Clonage excessif de `String` (gain: réduction allocations 10-20%)
---
## PHASE F — LISTE EXHAUSTIVE DES PROBLÈMES
### P0 — CRITIQUES (Build/Sécurité/Prod)
| ID | Titre | Impact | Fichier | Effort |
|---|---|---|---|---|
| MOD-P0-001 | Secrets hardcodés | Compromission auth | `config_rust.rs:234,46` | S |
| MOD-P0-002 | HMAC timing attack | Forgery signatures | `utils/crypto.rs:26-28` | S |
| MOD-P0-003 | Variables globales unsafe | Data race, crash | `metrics.rs:215` | M |
| MOD-P0-015 | Build cassé | Déploiement impossible | Multiple | M |
### P1 — HAUTE PRIORITÉ (Bugs/Dette)
| ID | Titre | Impact | Fichier | Effort |
|---|---|---|---|---|
| MOD-P1-004 | Dépendances manquantes | Build cassé | `Cargo.toml` | S |
| MOD-P1-005 | Modules manquants | Build cassé | `utils/mod.rs` | S |
| MOD-P1-006 | Exports manquants | Build cassé | `lib.rs` | S |
| MOD-P1-007 | Feature flag manquant | Build cassé | `Cargo.toml` | S |
| MOD-P1-008 | Validation JWT faible | Secrets faibles acceptés | `config_rust.rs:269` | S |
| MOD-P1-016 | Pas de healthcheck | Monitoring impossible | N/A | M |
| MOD-P1-017 | Logs non structurés | Analyse difficile | `validation.rs` | M |
| MOD-P1-018 | Pas de request_id | Traçabilité impossible | N/A | M |
| MOD-P1-019 | Pas de métriques auto | Pas de visibilité perf | `metrics.rs` | L |
### P2 — MOYENNE PRIORITÉ (Qualité/Perf)
| ID | Titre | Impact | Fichier | Effort |
|---|---|---|---|---|
| MOD-P2-009 | Regex non compilées | Performance | `validation.rs` | S |
| MOD-P2-010 | Trop de unwrap() | Panics possibles | Multiple | M |
| MOD-P2-011 | Pas validation entropie | Secrets faibles | `config_rust.rs` | S |
| MOD-P2-012 | Pas rate limit tokens | Abus possible | `auth.rs` | M |
| MOD-P2-020 | Pas de retry auto | Échecs transitoires | Traits | M |
| MOD-P2-021 | Pas de timeout | Blocages | Traits | M |
| MOD-P2-022 | Pas circuit breaker | Cascading failures | Traits | L |
| MOD-P2-023 | Pool DB non configuré | Latence | `config/database.rs` | S |
| MOD-P2-024 | Pas cache métriques | Allocations | `metrics.rs` | S |
| MOD-P2-025 | Clonage excessif | Allocations | Multiple | M |
### P3 — BASSE PRIORITÉ (Cosmétique)
| ID | Titre | Impact | Fichier | Effort |
|---|---|---|---|---|
| MOD-P3-014 | Logs peuvent exposer secrets | Fuite info | N/A | M |
| MOD-P3-026 | Documentation manquante | DX | Multiple | M |
| MOD-P3-027 | Tests incomplets | Couverture | Multiple | M |
| MOD-P3-028 | Duplication config | Maintenance | `config/` vs `config_rust.rs` | L |
---
## PHASE G — PLAN D'EXÉCUTION
### Checklist P0 (Ordre strict)
1. **MOD-P1-004**: Ajouter `rand` et `totp_rs` dans `Cargo.toml`
2. **MOD-P1-005**: Créer `src/utils/serialization.rs` ou supprimer déclaration
3. **MOD-P1-006**: Exporter `VezaError`, `VezaResult` dans `lib.rs`
4. **MOD-P1-007**: Ajouter feature `env-filter` à `tracing-subscriber`
5. **MOD-P0-001**: Supprimer secrets hardcodés, exiger env vars
6. **MOD-P0-002**: Remplacer comparaison HMAC par constante
7. **MOD-P0-003**: Remplacer `static mut` par `OnceLock`
8. **MOD-P0-015**: Vérifier `cargo check` passe
**Validation**: `cargo test --all-features` doit passer
### Checklist P1 (Par lots)
**Lot 1 — Validation & Sécurité**:
- MOD-P1-008: Renforcer validation JWT secret
- MOD-P2-011: Ajouter validation entropie
**Lot 2 — Observabilité**:
- MOD-P1-016: Implémenter healthcheck
- MOD-P1-017: Structurer tous les logs
- MOD-P1-018: Ajouter request_id partout
**Lot 3 — Robustesse**:
- MOD-P2-020: Ajouter retry dans traits
- MOD-P2-021: Ajouter timeouts
### Quick Wins (≤ 1h chacun)
1. **MOD-P2-009**: Regex compilées (30min)
2. **MOD-P2-023**: Configurer pool DB (30min)
3. **MOD-P1-008**: Validation JWT (30min)
### Tests à Ajouter en Priorité
1. **Tests de sécurité**:
- Timing attack sur HMAC
- Validation secrets JWT
- Secrets non exposés dans logs
2. **Tests de robustesse**:
- Concurrence sur `GLOBAL_METRICS`
- Retry avec backoff
- Timeouts
3. **Tests d'intégration**:
- Config complète depuis env vars
- Métriques end-to-end
- Healthcheck
### PR Plan
**PR #1: Fix Build (P0)**
- Titre: `fix: resolve compilation errors and missing dependencies`
- Contenu: MOD-P1-004, MOD-P1-005, MOD-P1-006, MOD-P1-007
- Tests: `cargo check` + `cargo test`
**PR #2: Security Fixes (P0)**
- Titre: `security: remove hardcoded secrets and fix HMAC timing attack`
- Contenu: MOD-P0-001, MOD-P0-002, MOD-P0-003
- Tests: Tests sécurité + `cargo test`
**PR #3: Observability (P1)**
- Titre: `feat: add healthcheck, structured logging, and request correlation`
- Contenu: MOD-P1-016, MOD-P1-017, MOD-P1-018
- Tests: Tests intégration
**PR #4: Performance (P2)**
- Titre: `perf: compile regexes and optimize allocations`
- Contenu: MOD-P2-009, MOD-P2-023, MOD-P2-024
- Tests: Benchmarks
**PR #5: Robustness (P2)**
- Titre: `feat: add retry, timeouts, and error handling improvements`
- Contenu: MOD-P2-010, MOD-P2-020, MOD-P2-021
- Tests: Tests robustesse
---
## BONUS — SPÉCIFICITÉS RUST
### Problèmes Rust-Spécifiques
1. **Async runtime misuse**: Pas de problème identifié (tokio bien utilisé)
2. **Blocking in async**: Pas de problème identifié
3. **Channels/backpressure**: Pas implémenté (à ajouter si nécessaire)
4. **Unwrap/expect**: 27 occurrences (MOD-P2-010)
5. **Feature flags**: Manquant pour `tracing-subscriber` (MOD-P1-007)
6. **Unsafe code**: `static mut` dans metrics (MOD-P0-003)
---
## RÉSUMÉ EXÉCUTIF
### État Actuel
- **Build**: CASSÉ (9 erreurs)
- **Tests**: Présents mais incomplets (~60% couverture)
- **Sécurité**: 3 vulnérabilités P0, 5 P1
- **Robustesse**: Manque observabilité, retry, timeouts
- **Performance**: Optimisations possibles (regex, allocations)
### Priorités Immédiates
1. **Fixer le build** (2h) PR #1
2. **Corriger vulnérabilités P0** (2h) PR #2
3. **Ajouter observabilité** (8h) PR #3
### Estimation Totale
- **P0**: 6h (1 sprint)
- **P1**: 20h (2-3 sprints)
- **P2**: 30h (3-4 sprints)
- **P3**: 15h (1-2 sprints)
**Total**: ~71h (7-10 jours de travail)
---
**Fin du rapport**