PHASE F — SÉCURITÉ FRONTEND
F1. Secrets et données sensibles
Variables VITE_* exposées au bundle
| Variable |
Sensible ? |
Verdict |
VITE_API_URL |
❌ Non — URL publique |
✅ OK |
VITE_WS_URL |
❌ Non — URL publique |
✅ OK |
VITE_STREAM_URL |
❌ Non — URL publique |
✅ OK |
VITE_UPLOAD_URL |
❌ Non — URL publique |
✅ OK |
VITE_APP_NAME |
❌ Non — branding |
✅ OK |
VITE_DEBUG |
⚠️ Potentiel — active le debug |
⚠️ S'assurer false en prod |
VITE_USE_MSW |
⚠️ Potentiel — active le mocking |
⚠️ S'assurer false en prod |
VITE_FCM_VAPID_KEY |
⚠️ Limité — clé publique Firebase |
✅ OK (clé publique par design) |
VITE_FEATURE_* |
❌ Non — feature flags |
✅ OK |
VITE_SENTRY_DSN |
❌ Non — DSN public par design |
✅ OK |
VITE_DOMAIN |
❌ Non — domaine public |
✅ OK |
Secrets dans le code source
- ✅ Aucun secret hardcodé détecté dans le code source
- ✅ Tokens de test uniquement dans les fichiers mock (
mocks/handlers.ts)
- ✅ Pas de clés API, mots de passe, ou secrets privés
Fichiers .env
| Fichier |
Tracké |
Verdict |
.env.example |
✅ Tracké (template) |
✅ OK |
.env.local |
❌ Non tracké |
✅ OK |
.env.storybook |
✅ Tracké |
⚠️ Vérifier qu'il ne contient pas de secrets |
.env.production |
✅ Tracké |
⚠️ Vérifier qu'il ne contient pas de secrets réels |
Stockage JWT
- ✅ httpOnly cookies — tokens JWT stockés dans des cookies httpOnly par le backend [services/tokenStorage.ts]
- ✅ JavaScript ne peut pas lire les tokens (getters retournent
null)
- ✅ Nettoyage des vestiges localStorage inclus
- ✅ Excellente pratique de sécurité
F2. XSS
dangerouslySetInnerHTML
| Fichier |
Ligne |
Source des données |
Sanitization |
Verdict |
features/chat/components/ChatMessages.tsx |
145 |
message.content (user input) |
✅ sanitizeChatMessage() |
✅ Sûr |
features/chat/components/virtualized-chat-messages/VirtualizedChatMessageItem.tsx |
58 |
message.content (user input) |
✅ sanitizeChatMessage() |
✅ Sûr |
Implémentation de la sanitization
Fichier : utils/sanitize.ts (429 lignes)
Configuration DOMPurify :
- Tags autorisés :
p, br, strong, em, u, i, b, span, a
- Attributs autorisés :
class, href, title, target
- URI schemes autorisés :
http, https, mailto uniquement
- Tags interdits :
script, iframe, object, embed, form, input, button
- Attributs interdits :
onerror, onload, onclick, onmouseover, onfocus, onblur
- Fallback de sanitization manuelle si DOMPurify indisponible
Verdict : ✅ Robuste. La sanitization est correctement implémentée avec DOMPurify et une configuration restrictive.
Autres vecteurs XSS
- ✅ Aucun
eval() ou new Function() détecté
- ✅ Aucun
.innerHTML = direct
- ✅ Aucun
document.write
- ✅ React échappe automatiquement le rendu JSX par défaut
F3. Stockage client
localStorage
| Donnée |
Fichier |
Sensible ? |
Verdict |
| Density preference |
features/tracks/components/TrackGrid.tsx:60,84 |
❌ Non |
✅ OK |
| (Legacy token cleanup) |
services/tokenStorage.ts |
— |
✅ Nettoyé |
sessionStorage
| Donnée |
Fichier |
Sensible ? |
Verdict |
| Deprecation warnings |
services/api/client.ts:773-774,872-884 |
❌ Non |
✅ OK |
| API error tracking |
services/api/client.ts:1347 |
❌ Non |
✅ OK |
Verdict : ✅ Aucune donnée sensible en localStorage/sessionStorage. Les tokens sont dans des cookies httpOnly.
F4. Dépendances
Build cassé
- 🔴 Le build échoue :
educationService manquant (import fantôme dans useEducationView.ts)
- Cela empêche l'exécution de
npm audit sur un build propre
Dépendances notables
| Dépendance |
Version |
Risque |
dompurify |
^3.3.0 |
✅ Dernière version — sanitization XSS |
axios |
^1.13.5 |
✅ Récent |
react |
^18.2.0 |
✅ Stable |
zod |
^3.25.76 |
✅ Validation schema |
swagger-ui-react |
^5.31.0 |
⚠️ En prod deps — potentiel d'attaque via UI Swagger exposée |
lucide-react |
^0.321.0 |
⚠️ Version ancienne (2024) — mise à jour recommandée |
F5. Autres vecteurs
CORS
- ✅ Proxy configuré en dev (
vite.config.ts) — pas de CORS issues en dev
- ✅
withCredentials: true dans le client Axios pour les cookies
- [DONNÉES INSUFFISANTES — CORS headers côté serveur non analysés]
CSP
- ✅ Utilitaire CSP présent (
utils/csp.ts)
- ✅ Production CSP utilise des nonces (pas de
unsafe-inline pour scripts)
- ✅ Dev CSP autorise
unsafe-eval pour Vite HMR uniquement
- ⚠️ Les headers CSP doivent être injectés côté serveur — vérifier l'intégration
CSRF
- ✅ Implémenté (
services/csrf.ts)
- ✅ Token CSRF récupéré depuis
/csrf-token endpoint
- ✅ Stocké en mémoire (pas en localStorage)
- ✅ Header
X-CSRF-Token injecté via intercepteur Axios
- ✅ Mécanisme de refresh avec déduplification
Open redirects
- ✅ Aucune assignation
window.location = détectée avec input utilisateur
- ✅ Navigation via React Router uniquement
Prototype pollution
- ✅ Pas d'usage de
lodash.merge ou patterns similaires dangereux détectés
Classement des vulnérabilités
| Gravité |
Vulnérabilité |
Localisation |
Exploitabilité |
Urgence |
| 🟡 MOYENNE |
Build cassé — import fantôme bloque le build |
useEducationView.ts → educationService |
Non exploitable (build-time) |
🔴 Immédiate — bloque le déploiement |
| 🟡 MOYENNE |
VITE_DEBUG / VITE_USE_MSW en production |
Config env |
Faible — info disclosure |
⚠️ Vérifier les valeurs en prod |
| 🟡 MOYENNE |
Swagger UI en production deps |
package.json |
Faible — surface d'attaque via Swagger UI |
⚠️ Déplacer en devDependencies ou lazy-load |
| 🟢 BASSE |
.env.production tracké |
.env.production |
Très faible — si ne contient que des valeurs publiques |
🟢 Vérifier le contenu |
| 🟢 BASSE |
CSP headers non vérifiés côté serveur |
Server config |
Dépend du serveur |
🟢 Audit serveur nécessaire |
SCORE SÉCURITÉ : 8/10
Points gagnés
| Point |
Score |
Justification |
| JWT httpOnly cookies |
+2.0 |
Excellente pratique — tokens inaccessibles au JS |
| XSS sanitization |
+1.5 |
DOMPurify strict, pas d'eval, pas d'innerHTML |
| CSRF protection |
+1.5 |
Token CSRF en mémoire, header injection |
| Pas de secrets hardcodés |
+1.0 |
Aucun secret dans le code source |
| CSP utilities |
+0.5 |
Utilitaire prêt avec nonces |
| No open redirects |
+0.5 |
Navigation React Router uniquement |
| No prototype pollution |
+0.5 |
Pas de patterns dangereux |
Points perdus
| Point |
Score |
Justification |
| Build cassé |
-0.5 |
Import fantôme bloque le déploiement |
| Swagger UI en prod deps |
-0.3 |
Surface d'attaque potentielle |
| Debug flags en env |
-0.2 |
VITE_DEBUG pourrait être activé en prod |