veza/docs/REMEDIATION_PROGRESS.md
senke fae4588d70 fix(security): update or remove vulnerable npm devDependencies (A06)
- Remove @lhci/cli, newman, pa11y-ci (used only by obsolete Makefile.old)
- Redirect qa:postman, qa:lh, qa:a11y scripts to explanatory message
- npm audit fix for remaining lodash vulnerability
- Document Lot 6 (bypass flags verified) and Lot 8 in REMEDIATION_PROGRESS
2026-02-16 10:20:10 +01:00

12 KiB
Raw Blame History

Progression de la remédiation — Stabilisation frontend

Référence : Plan de remédiation
Dernière mise à jour : 16 février 2026 (Phases 46 complétées, vulnérabilités npm Phase 1, rate limiting A04, audit sécurité)


Audit sécurité (AUDIT_TECHNIQUE_INTEGRAL_2026_02_16)

Référence : Plan de remédiation sécurité

Lot 2 — Routes Education fantômes (A01)

  • Constat : Les packages internal/api/education/ et internal/core/education/ étaient des répertoires vides (aucun fichier Go, aucune route enregistrée).
  • Action : Suppression des répertoires vides. Aucune route Education n'était exposée ; le risque identifié dans l'audit ne s'appliquait pas au code actuel.

Lot 6 — Bypass flags (A05)

  • Constat : BYPASS_CONTENT_CREATOR_ROLE et CSRF_DISABLED sont déjà rejetés en production via validateNoBypassFlagsInProduction().
  • Vérification : NewConfig() appelle ValidateForEnvironment() qui invoque validateNoBypassFlagsInProduction(c.Env) au démarrage. Aucun changement nécessaire.

Lot 8 — Vulnérabilités npm (A06)

  • Action : Suppression de @lhci/cli, newman, pa11y-ci (devDependencies avec vulnérabilités, utilisées uniquement par Makefile.old obsolète).
  • Scripts : qa:postman, qa:lh, qa:a11y redirigés vers message explicatif.
  • Résultat : 25 vulnérabilités → 1 modérée restante (dépendance transitive). Risque accepté pour dev deps.

Vulnérabilités npm (A06 — Phase 1)

Référence : AUDIT_TECHNIQUE_INTEGRAL_2026_02.md section A06.

Correctifs appliqués

  • npm audit fix : brace-expansion, diff, undici corrigés automatiquement.
  • React Router XSS (GHSA-2w69-qvjg-hvjx) : react-router-dom mis à jour vers ^6.30.3 (@remix-run/router 1.23.2).
  • Axios DoS (GHSA-43fc-jf86-j433) : override axios >= 1.13.5 dans package.json racine.
  • class-variance-authority : réintégré (dépendance manquante pour button/card).
  • CI : npm audit --audit-level=high exécuté depuis la racine du monorepo.

Vulnérabilités restantes (devDependencies uniquement)

25 vulnérabilités dans @lhci/cli, newman, pa11y-ci (cookie, jose, lodash, node-forge, qs, semver, tar-fs, tmp, ws). Risque accepté : ces packages ne sont pas inclus dans le build de production. Correction via npm audit fix --force entraînerait des breaking changes (downgrade @lhci/cli, newman, pa11y-ci).


Rate limiting (A04)

Référence : AUDIT_TECHNIQUE_INTEGRAL_2026_02.md — Points de rupture (ligne 170), A04 (ligne 232).

Correctifs appliqués

  • Rate limiting toujours actif : suppression de la condition Env != EnvDevelopment pour le rate limit global et register.
  • Limites assouplies en dev : getDefaultRateLimitLimit(env) — 1000 req/min en dev/test, 200 en staging/prod.
  • Register assoupli en dev : getDefaultRegisterAttempts(env) — 20 inscriptions/heure en dev/test, 3 en staging/prod.
  • Documentation : README mis à jour avec tableau des limites par environnement.

Phase 1 — Backend solide

1.1 Sécurité backend

  • .gitignore : Renforcement des patterns pour .env, .env.*, **/.env, **/.env.local, veza-*/.env, apps/web/.env.local (ne jamais committer de secrets).
  • Chat server : Dans veza-chat-server/src/jwt_manager.rs, validate_access_token vérifie désormais en base que lutilisateur existe (si db_pool disponible) ; pas de fallback « user » si absent en DB — connexion refusée.
  • Backend Go : Le handler de refresh token vérifie déjà lexistence de lutilisateur en DB (voir internal/core/auth/service.go RefreshToken).
  • Pagination : Contrôle strict page >= 1 et 1 <= limit <= 100 avec retour 400 et message clair dans :
    • internal/handlers/playlist_handler.go (GetPlaylists),
    • internal/handlers/profile_handler.go (ListUsers),
    • internal/core/track/handler.go (ListTracks).

1.2 API et contrats

  • Healthcheck : Les Dockerfiles (Dockerfile, Dockerfile.production) utilisent déjà http://localhost:8080/api/v1/health.
  • go-clamd : Documenté dans veza-backend-api/docs/CLAMAV_SETUP.md (limitation : lib abandonnée ; désactivation via ENABLE_CLAMAV=false = pas de scan).
  • Search : Contrat documenté dans veza-backend-api/docs/API_DOCUMENTATION.md — recherche par ressource (/api/v1/tracks/search, /api/v1/playlists/search, /api/v1/users/search) ; pas dendpoint unifié GET /api/v1/search.
  • Endpoints marketplace / social : Routes existantes (wishlist, panier, groups) ; pas de 501 ajouté.

1.3 Services Rust

  • Redis : Versions alignées (redis 0.32) dans veza-chat-server et veza-stream-server (Cargo.toml).

1.4 Infra et CD

  • Docker-compose : Mots de passe en dur remplacés par variables denvironnement (POSTGRES_PASSWORD, RABBITMQ_DEFAULT_PASS, etc.) avec valeurs par défaut pour le dev dans docker-compose.yml.
  • CD : Commentaire ajouté dans .github/workflows/cd.yml : pour pousser vers un registry, configurer les secrets DOCKER_REGISTRY, DOCKER_REGISTRY_USERNAME, DOCKER_REGISTRY_PASSWORD.

Phase 2 — Frontend : bugs et comportements critiques

2.1 Auth et 2FA

  • 2FA login : Implémenté. Backend : POST /api/v1/auth/login/2fa (body : email, password, code, remember_me) ; frontend : completeLogin2FA() dans apps/web/src/services/api/auth.ts, action complete2FALogin dans le store, flux dans LoginPage (affichage TwoFactorVerify quand requires_2fa, puis appel API et redirection).
  • Typage auth : Traité dans apps/web/src/services/api/auth.ts (réponse typée LoginResponse/RegisterResponse, options logout typées, isAxiosError pour les erreurs).
  • Redirect si déjà authentifié : LoginPage / RegisterPage utilisent authStore / useUser ; à vérifier en conditions réelles (pas de boucle login → redirect).

2.2 Memory leaks et logs

  • setTimeout : ChatInput, SocialViewFeedItem, PostCard ont déjà un cleanup (clearTimeout dans le return du useEffect).
  • console.log : GlobalSearchBar utilise logger.debug ; pas de suppression massive demandée pour linstant.

2.3 Accessibilité

  • ChatInput : Le champ principal a déjà aria-label="Type a message".
  • Sidebar (layout) : components/layout/Sidebar.tsx utilise déjà FocusTrap quand la sidebar est ouverte en mobile (sidebarOpen && isMobile).

Phase 3 — Tests (en cours)

  • Vitest : Suite complète 0 échec (265 fichiers passés, 4 skippés ; 3230 tests passés, 87 skippés). Corrections appliquées :
    • SettingsPage.test.tsx : Load error → assertion sur getByRole('alert') + contenu flexible ; save error → reset de settingsSchema.safeParse dans beforeEach (évite que le test « validation errors » laisse safeParse en échec pour le test suivant) ; userEvent pour le clic Save.
    • RegisterPage.test.tsx : Terms → assertion sur « handleRegister non appelé » + optionnel message terms ; username « déjà pris » → getAllByText (plusieurs nœuds affichent le message) ; vérification notice → findByText + act autour du mock + rerender ; email dans la notice → texte partiel + test@example.com (texte split dans le DOM).
    • ForgotPasswordForm.test.tsx : « should disable form while loading » → attente après waitFor pour que la promesse mock se résolve avant teardown (évite « state update after unmount »).
    • usePlaybackRealtime.test.ts : 8 tests réactivés dans un second describe avec vrais timers (WebSocket lifecycle) ; plus de skip.
  • Tests par groupes (machines limitées) : Vitest configuré pour limiter RAM/CPU (pool: 'threads', maxThreads: 2, fileParallelism: false). Scripts npm ajoutés pour exécuter les tests par groupe : test:auth, test:tracks, test:playlists, test:player, test:streaming, test:settings-profile-chat, test:components-ui, test:components-other, test:services, test:hooks, test:misc. Commande test:groups lance tous les groupes séquentiellement. Ordre recommandé pour le diagnostic : petits groupes d'abord (settings-profile-chat, streaming, hooks, misc) puis les plus gros.
  • Providers / mocks : Wrappers dans src/test/ ; MSW dans src/mocks/. À aligner sur les contrats API si besoin.
  • Storybook : npm run test:storybook (script scripts/audit-storybook.js) nécessite Storybook servi sur port 6007 ; lancer npm run build-storybook puis servir le dossier storybook-static sur 6007, puis npm run test:storybook.
  • E2E : Playwright (npm run test:e2e). Parcours critiques et fichiers listés dans apps/web/e2e/README.md (auth, smoke, playlists, search, profile, upload). Test search : e2e/tests/search.spec.ts (navigation /search, saisie requête, résultats ou état vide). Test 2FA : dans auth.spec.ts (skippé sauf si E2E_2FA_CODE et compte 2FA configurés).

Phase 4 — Dette structurante

  • Loading : Composants centralisés en place — LoadingState, LoadingSpinner, Skeleton, ButtonLoading ; guide apps/web/src/docs/LOADING_STATES_PATTERN.md mis à jour avec section LoadingState et recommandation (full-page/block → LoadingState, list/card → Skeleton).
  • Modal → Dialog : Modal déprécié (S1.4) ; Dialog sappuie dessus. Feature modals récents utilisent déjà Dialog. Préférer Dialog pour tout nouveau code.
  • Track type : Commentaire ajouté dans apps/web/src/features/tracks/types.ts — source of truth pour Track = features/player/types ; champs upload/backend = features/tracks/types/track.ts.
  • Interceptors : Documenté en en-tête dans interceptors.ts ; pas de découpage supplémentaire pour linstant.

Phase 5 — Features fantômes et cohérence

  • Coming Soon : Routes documentées dans apps/web/docs/FEATURE_STATUS.md/gear, /live, /education, /queue, /developer (placeholder ComingSoon dans routeConfig.tsx).
  • Feature flags : Référence dans FEATURE_STATUS.md vers src/config/features.ts et VITE_FEATURE_* ; liste des flags (TWO_FACTOR_AUTH, PLAYLIST_*, HLS_STREAMING, ROLE_MANAGEMENT, NOTIFICATIONS).
  • Marketplace / groups / search : Mention dans FEATURE_STATUS.md (routes marketplace, search par ressource, groups dans Social).
  • Typo : useLibraryManager.ts — message « coming soon available » corrigé en « coming soon — available in the next release ».

Phase 6 — Maturité

  • TypeScript : npx tsc --noEmit exécuté — 0 erreur.
  • Docs : FEATURE_STATUS.md créé (Coming Soon + feature flags + marketplace/search) ; LOADING_STATES_PATTERN.md enrichi ; REMEDIATION_PROGRESS.md à jour.
  • UX : Checklist finale rappelée ci-dessous (skip link, aria-label, focus trap, pas de console.log en prod).

Checklist de validation finale (rappel)

  • npx vitest run : 0 échec (ou < 5 % skippés avec ticket). Sur machine limitée en RAM/CPU : utiliser npm run test:groups ou les scripts par groupe (test:auth, test:tracks, etc.) pour éviter la saturation des ressources.
  • npm run build : succès sans warning bloquant.
  • npx tsc --noEmit : 0 erreur.
  • npm run test:storybook : 0 erreur. Procédure de validation Storybook sur 6007 :
    1. cd apps/web && npm run build-storybook
    2. Démarrer le serveur sur le port 6007 : node scripts/serve-storybook-static.cjs (ou npx serve storybook-static -l 6007) et le laisser tourner
    3. Dans un autre terminal : npm run test:storybook (le script scripts/audit-storybook.js cible http://localhost:6007 et ne démarre pas le serveur). Option : npm run test:storybook:playwright démarre automatiquement le serveur via playwright.config.storybook.ts.
  • Aucun console.log / debug en prod.
  • Skip link + aria-label ChatInput + focus trap Sidebar en place.
  • 2FA login : backend à compléter puis frontend à brancher.