COULISSES
Grand Gaz est un projet perso, construit seul. Cette page montre comment il est protégé, sans cacher ce qui reste imparfait. Tout ce qui est décrit ici existe dans le code du site.
Comptes et sessions
- EN PLACEMots de passe hachés. Ils ne sont jamais stockés en clair : hachage
password_hash(), vérifié avecpassword_verify(). - EN PLACEAnti-fixation de session. L’identifiant de session est régénéré à la connexion et à l’inscription (
session_regenerate_id(true)). - EN PLACECookies de session durcis.
HttpOnly,SameSite=Lax,Securedès que la requête arrive en HTTPS, mode strict activé et cookies uniquement (pas d’identifiant dans l’URL).
Limitation des tentatives
Les compteurs sont stockés côté serveur, pas dans la session. Un premier système les gardait en session : un attaquant qui n’envoie pas de cookie repartait de zéro à chaque essai. Il a été remplacé.
- EN PLACEClés hachées en SHA-256, écritures verrouillées (
flock) pour éviter les courses entre requêtes, nettoyage automatique des compteurs périmés. - EN PLACEDerrière un proxy, l’IP retenue est la dernière entrée de
X-Forwarded-For(celle ajoutée par le proxy lui-même) et elle est validée : un visiteur ne peut pas choisir son adresse en forgeant l’en-tête.
Requêtes, formulaires et en-têtes
- EN PLACEJeton CSRF de 32 octets aléatoires (
random_bytes), comparé en temps constant (hash_equals). Pour les appels AJAX, le jeton OU une preuve que la requête vient du même site (Fetch MetadataSec-Fetch-Site, sinonOrigin/Referer). - EN PLACEBase de données : accès PDO avec requêtes préparées pour les valeurs venant de l’utilisateur ; sorties de pages échappées avec
htmlspecialchars. - EN PLACEEn-têtes HTTP :
X-Content-Type-Options: nosniff,X-Frame-Options: SAMEORIGIN,Referrer-Policy,Permissions-Policy(géolocalisation, micro et caméra refusés). - EN PLACEContent-Security-Policy : seuls les domaines réellement utilisés par le site sont autorisés (polices, icônes, météo, notifications, API de données F1).
object-src 'none'etbase-uri 'self'ferment deux classiques d’injection.
Fichiers et dossiers protégés
- EN PLACELes secrets sont dans un fichier
.envinaccessible depuis le web, commecomposer.json/lock, les fichiers.sql, les.loget les scripts de test ou de debug. - EN PLACELes dossiers
includes/etcache/refusent tout accès direct : ils ne sont lus que par le code PHP. - EN PLACEListage des dossiers désactivé (
Options -Indexes), pages d’erreur 404 et 500 génériques qui ne révèlent rien de l’infrastructure. - EN PLACELes journaux de tâches planifiées font l’objet d’une rotation pour ne pas grossir sans limite.
Signaler une faille
Le site publie un fichier security.txt (standard RFC 9116) avec un contact et une date d’expiration.
Si tu trouves quelque chose, dis-le : c’est le but.
Mini-SIEM : surveiller les logs Apache
Protéger ne suffit pas, il faut aussi voir ce qui se passe. Je construis un petit SIEM en Python qui lit les logs Apache de Grand Gaz et fait ressortir les comportements suspects.
- EN COURSForce brute : rafales de
POSTsur la page de connexion, par IP. - EN COURSReconnaissance : demandes de chemins typiques (
.env,wp-login.php,phpmyadmin…) et pics de404. - EN COURSSignaux faibles : user-agents d’outils de scan, volumes anormaux sur une courte durée.
Ce qui reste à améliorer
La sécurité n’est jamais finie. Voici les points que je connais et que je compte traiter :
- À FAIRECSP plus stricte :
'unsafe-inline'est encore autorisé pour les scripts et les styles (beaucoup de code inline), et'unsafe-eval'apparaît côté Apache. La piste : des nonces et la sortie du JavaScript en fichiers. - À FAIREUne seule CSP : elle est aujourd’hui définie à deux endroits (Apache et PHP). Il faut n’en garder qu’une pour éviter qu’elles divergent.
- À FAIRELimitation partagée : les compteurs sont des fichiers locaux, suffisants sur un seul serveur. Avec plusieurs serveurs, il faudrait un stockage commun.