veza/veza-backend-api/docs/archive/AUDIT_CONFIG.md
senke b103a09a25 chore: consolidate CI, E2E, backend and frontend updates
- CI: workflows updates (cd, ci), remove playwright.yml
- E2E: global-setup, auth/playlists/profile specs
- Remove playwright-report and test-results artifacts from tracking
- Backend: auth, handlers, services, workers, migrations
- Frontend: components, features, vite config
- Add e2e-results.json to gitignore
- Docs: REMEDIATION_PROGRESS, audit archive
- Rust: chat-server, stream-server updates
2026-02-17 16:43:21 +01:00

7.9 KiB

🔍 AUDIT DE SÉCURITÉ - Configuration Backend Go

Date: 2025-01-XX
Fichiers analysés: internal/config/config.go, internal/api/router.go, internal/middleware/cors.go


1. STRUCTURE ACTUELLE

1.1. Représentation de la configuration

  • Struct principale: config.Config (ligne 24-79 de config.go)

    • Mélange de services initialisés (Database, Redis, Services, Middlewares) et de valeurs de configuration (AppPort, JWTSecret, CORSOrigins, etc.)
    • Pattern: Singleton créé via NewConfig() qui initialise tout (DB, Redis, Services, Middlewares)
  • Initialisation:

    • NewConfig() (ligne 82) : fonction globale qui charge tout
    • Load() (ligne 384) : fonction alternative qui charge seulement EnvConfig (struct plus simple)
    • Problème: Deux chemins de chargement différents, confusion possible
  • Variables globales:

    • Pas de variables globales explicites, mais NewConfig() crée un singleton qui est passé partout
    • Pattern acceptable mais peut être amélioré

1.2. Sources de vérité

Ordre de priorité actuel:

  1. Variables d'environnement système (priorité maximale)
  2. Fichiers .env.{env} (ex: .env.development)
  3. Fichiers .env (fallback)
  4. Valeurs par défaut hardcodées dans le code

Variables critiques chargées:

  • JWT_SECRET: REQUIS (ligne 117) - getEnvRequired() → panic si absent
  • DATABASE_URL: REQUIS (ligne 124) - getEnvRequired() → panic si absent
  • CORS_ALLOWED_ORIGINS: ⚠️ DÉFAUT DANGEREUX (ligne 101) - getEnvStringSlice(..., []string{"*"})wildcard par défaut
  • REDIS_URL: ⚠️ Valeur par défaut "redis://localhost:6379" (ligne 122)
  • APP_PORT: Valeur par défaut 8080 (ligne 113)
  • CHAT_JWT_SECRET: Fallback vers JWT_SECRET si non défini (ligne 121)

Détection d'environnement:

  • DetectEnvironment() (ligne 28 de env_detection.go): Priorité APP_ENV > NODE_ENV > GO_ENV > hostname > development
  • Problème: L'environnement est détecté mais pas utilisé pour différencier les comportements (CORS, validation, etc.)

1.3. Points de risque sécurité identifiés

🔴 CRITIQUE - CORS Wildcard par défaut

  • Ligne 101 de config.go: corsOrigins := getEnvStringSlice("CORS_ALLOWED_ORIGINS", []string{"*"})
  • Impact: Si CORS_ALLOWED_ORIGINS n'est pas défini, toutes les origines sont autorisées
  • Risque: En production, si la variable est oubliée, l'API accepte les requêtes de n'importe quel domaine
  • Ligne 62 de router.go: Fallback vers CORSDefault() si CORSOrigins est vide → double risque

🟠 MOYEN - Pas de validation CORS selon environnement

  • Ligne 483-544 de config.go: Validate() ne vérifie pas que CORS n'est pas "*" en production
  • Impact: Aucune protection contre le wildcard en prod
  • Risque: Configuration dangereuse peut passer inaperçue

🟠 MOYEN - Valeurs par défaut trop permissives

  • REDIS_URL: Valeur par défaut hardcodée (acceptable en dev, dangereux si oublié en prod)
  • APP_PORT: Valeur par défaut (acceptable)
  • Impact: En prod, si variables manquantes, l'app démarre avec des valeurs dev

🟡 FAIBLE - Pas de distinction dev/test/prod

  • L'environnement est détecté mais pas utilisé pour:
    • Changer les defaults CORS
    • Valider différemment selon l'env
    • Refuser de démarrer si config critique manque en prod

🟡 FAIBLE - Debug logs potentiels en prod

  • Ligne 417-420 de config.go: fmt.Printf dans getEnv()logs de debug en production
  • Impact: Fuite d'information sur les valeurs de config (même si masquées ailleurs)

1.4. Configuration CORS

Fichier: internal/middleware/cors.go

  • Fonction CORS(allowedOrigins []string):
    • Accepte une liste d'origines
    • Si "*" est dans la liste → toutes les origines autorisées (ligne 36)
    • Headers autorisés: Authorization, Content-Type (ligne 20)
    • Méthodes autorisées: GET, POST, PUT, DELETE, OPTIONS (ligne 19)
    • Access-Control-Allow-Credentials: true (ligne 21)

Fichier: internal/api/router.go

  • Ligne 59-63:
    if r.config != nil && len(r.config.CORSOrigins) > 0 {
        router.Use(middleware.CORS(r.config.CORSOrigins))
    } else {
        router.Use(middleware.CORSDefault()) // ← DANGER: wildcard par défaut
    }
    

Problèmes identifiés:

  1. Le middleware CORS est bien configuré via la config
  2. Fallback vers CORSDefault() si liste vide → wildcard
  3. Pas de validation que "*" n'est pas utilisé en prod
  4. Pas de distinction dev/prod pour les origines par défaut

2. DESIGN CIBLE PROPOSÉ

2.1. Profils d'environnement

Environnements supportés:

  • development: Logs verbeux, CORS permissif (localhost uniquement)
  • test: Config adaptée aux tests (DB test, pas de side-effects)
  • production: Strict - aucune valeur par défaut dangereuse, validation stricte

2.2. Comportements attendus

Development

  • CORS par défaut: ["http://localhost:3000", "http://127.0.0.1:3000"] si CORS_ALLOWED_ORIGINS non défini
  • Logs: DEBUG/INFO
  • Validation: Permissive (valeurs par défaut acceptées)

Test

  • CORS: Liste vide ou configurée explicitement
  • DB: URL de test requise
  • Validation: Stricte mais adaptée aux tests

Production

  • CORS: CORS_ALLOWED_ORIGINS REQUIS et non vide
  • CORS: Interdiction explicite de "*" en prod
  • Validation: Erreur fatale si variables critiques manquantes
  • Logs: INFO/WARN/ERROR uniquement (pas de DEBUG)

2.3. Chargement de la config

Fonction unique: LoadConfigFromEnv() (*AppConfig, error)

  • Charge depuis variables d'environnement uniquement
  • Valide selon l'environnement détecté
  • Retourne erreur si config invalide en prod

Struct simplifiée (pour la partie config pure):

type AppConfig struct {
    Env                string   // development, test, production
    HttpPort           string
    DatabaseURL        string
    RedisURL           string
    JwtSecret          string
    ChatJWTSecret      string
    CorsAllowedOrigins []string
    // ... autres champs
}

2.4. Validation renforcée

Nouvelle fonction: ValidateForEnvironment(cfg *AppConfig) error

  • En production:
    • CORS_ALLOWED_ORIGINS doit être défini et non vide
    • CORS_ALLOWED_ORIGINS ne doit pas contenir "*"
    • Toutes les variables critiques doivent être présentes
  • En development:
    • Valeurs par défaut acceptées
    • Warning si config incomplète mais démarrage autorisé

3. PLAN D'IMPLÉMENTATION

Étape 1: Refactor config.go

  • Ajouter champ Env dans Config
  • Modifier NewConfig() pour utiliser l'environnement détecté
  • Créer validateForEnvironment() avec règles strictes selon env
  • Modifier defaults CORS selon environnement

Étape 2: Mettre à jour router.go

  • Supprimer fallback CORSDefault()
  • Utiliser strictement config.CorsAllowedOrigins
  • Ajouter validation au démarrage

Étape 3: Tests

  • Test dev avec defaults
  • Test prod avec CORS manquant → erreur
  • Test prod avec CORS="*" → erreur
  • Test prod valide

Étape 4: Documentation

  • Créer docs/BACKEND_CONFIG.md
  • Lister variables d'environnement
  • Expliquer différences dev/prod

4. RÉSUMÉ DES RISQUES

Risque Sévérité Fichier Ligne Action requise
CORS wildcard par défaut 🔴 CRITIQUE config.go 101 Valeur par défaut selon env
Fallback CORSDefault() 🔴 CRITIQUE router.go 62 Supprimer, erreur si vide
Pas de validation CORS prod 🟠 MOYEN config.go 483 Ajouter validation selon env
Debug logs en prod 🟡 FAIBLE config.go 417 Supprimer fmt.Printf
Pas de distinction dev/prod 🟡 FAIBLE config.go 82 Utiliser env détecté

Prochaines étapes: Implémentation des corrections identifiées.