Projet personnel · 09/2026
Audit de sécurité de djuju02.fr
Ce site est en production : portfolio, overlays de stream, bots Twitch et Discord, webhooks ouverts sur Internet et console d'administration, sur un hébergement mutualisé. Je l'ai audité en boîte blanche, puis j'ai corrigé et vérifié chaque constat.
Réalisé avec une assistance d'IA.
- 0 faille critique ou élevée
- 9 constats, tous traités
- 43 points d'entrée PHP relus
- 0 secret dans l'historique Git
Périmètre et méthode
Code
Chaque point d'entrée relu : authentification, CSRF, échappement des sorties, envois de fichiers, lectures de fichiers, requêtes sortantes, webhooks, OAuth, et manipulation du DOM en JavaScript.
Historique Git
Tous les commits parcourus à la recherche de secrets. Un secret retiré du code reste lisible dans les versions précédentes.
Production
Tests passifs uniquement : en-têtes, cookies, fichiers sensibles, listage des dossiers, méthodes HTTP. Ni force brute, ni saturation.
Constats et correctifs
-
Moyenne
Clé d'administration acceptée dans l'URL
Deux outils internes acceptaient la clé en paramètre d'URL : aucune limite de tentatives, et la clé restait lisible dans les journaux du serveur et l'historique du navigateur.
Correctif : Session d'administration exigée, avec jeton CSRF pour chaque action.
-
Moyenne
Sessions privilégiées sans expiration
Une session d'administration restait valide tant que le cookie existait : aucune limite côté serveur.
Correctif : Expiration après 2 h d'inactivité et 12 h au maximum ; purge des sessions périmées.
-
Moyenne
HSTS absent
Une première visite en HTTP pouvait être interceptée avant la redirection vers HTTPS.
Correctif : En-tête Strict-Transport-Security activé pour un an.
-
Faible
Interactions Discord rejouables
La signature Ed25519 était vérifiée, mais pas l'horodatage signé : une requête interceptée restait valable indéfiniment.
Correctif : Fenêtre de validité de 5 minutes.
-
Faible
Téléchargement distant non contrôlé
Des images récupérées depuis une URL externe étaient écrites dans le dossier public sans contrôle du domaine, de la taille ni du contenu.
Correctif : HTTPS vers le CDN Twitch uniquement, 2 Mo au maximum, signature JPEG ou PNG vérifiée.
-
Faible
Déconnexion sans jeton CSRF
Un site tiers pouvait déconnecter un administrateur à son insu.
Correctif : Jeton CSRF exigé sur toutes les pages concernées.
-
Faible
Code d'accès trop court
Un espace privé acceptait un code de 8 caractères, protégé seulement par un verrou par adresse IP, que l'on contourne en changeant d'adresse.
Correctif : Longueur minimale portée à 12 caractères.
-
Info
Serveur de déploiement non authentifié
Sans empreinte connue, le déploiement SFTP acceptait la clé présentée par le serveur à chaque exécution.
Correctif : Empreinte du serveur vérifiée hors ligne et figée dans un secret GitHub.
-
Info
Port explicite dans les redirections
Certaines redirections sortaient en « :443 ». Sans risque, mais signe de règles de réécriture imprécises.
Correctif : Cibles de redirection absolues, sans port.
Vérification
Chaque correctif a été éprouvé en local avant la mise en ligne. Par exemple, une interaction Discord correctement signée mais datée de 15 minutes est refusée, et une déconnexion forgée depuis un autre site reste sans effet.
Puis en production : HSTS présent, clé passée dans l'URL refusée, pages principales toujours accessibles.
Ce qui était déjà solide
- Content Security Policy stricte, sans
unsafe-inlineniunsafe-eval, et aucune donnée externe insérée comme HTML. - Toutes les sorties PHP échappées, données structurées JSON-LD comprises.
- Jeton CSRF sur chaque formulaire qui modifie des données.
- Webhooks Twitch (HMAC-SHA256) et Discord (Ed25519) vérifiés en temps constant, avec déduplication des messages Twitch.
- Jetons OAuth chiffrés en AES-256-GCM ; secrets hors du dépôt et hors du dossier public.
- Fichiers envoyés contrôlés sur leur contenu réel et stockés hors du dossier public.
- Formulaire de contact limité en fréquence et protégé contre l'injection d'en-têtes d'e-mail.
Empêcher la régression
Un correctif ne vaut que s'il survit aux modifications suivantes. Chaque mise en ligne passe désormais par GitHub Actions, et le moindre échec bloque le déploiement.
Avant l'envoi
- Scan de tout l'historique avec gitleaks
- Aucun script, style ou gestionnaire d'événement en ligne
- Aucune insertion de HTML en JavaScript
- CSP jamais affaiblie
- Fichiers compilés identiques à leurs sources
Chaîne d'approvisionnement
- Actions GitHub figées par empreinte de commit
- Jeton GitHub en lecture seule
- Outils téléchargés vérifiés par SHA-256
- Secrets transmis par l'environnement, jamais insérés dans le script
Après l'envoi
- En-têtes de sécurité présents
- Redirection HTTP vers HTTPS
- Fichiers de configuration et secrets inaccessibles
Limites
Hors périmètre : la résistance aux attaques par saturation, les tentatives de force brute, et la configuration du compte chez l'hébergeur. La bibliothèque embarquée (React 18.3.1) a été vérifiée après coup : aucune vulnérabilité connue ne la concerne.
- Revue de code
- OWASP Top 10
- CSRF
- CSP
- HSTS
- HMAC / Ed25519
- gitleaks
- GitHub Actions
- Supply chain