Le contrôle des bagages à l'aéroport
Le contrôle des billets (pare-feu réseau) vérifie que vous allez au bon terminal. Le scanner des bagages (WAF) regarde ce que vous transportez. Les deux sont utiles, et aucun ne remplace l'autre.
Le pare-feu applicatif web (WAF) qui lit le contenu des requêtes HTTP - règles, ModSecurity et OWASP CRS, faux positifs, contournements -, puis les principes du développement sécurisé - entrées non fiables, moindre privilège, erreurs discrètes, secrets hors du code, dépendances à jour - et les en-têtes de sécurité HTTP.
Le pare-feu réseau de la leçon précédente laisse passer le port 443, et il le doit : c'est par là qu'arrivent les clients. Mais c'est aussi par là qu'arrivent les injections SQL et le XSS. Le pare-feu applicatif ouvre chaque requête HTTP pour en lire le contenu. Il aide, mais la vraie protection reste un code écrit avec de bonnes habitudes : c'est le développement sécurisé, qui termine ce module.
Une recherche normale, q=savon, arrive sur le port 443 : le pare-feu réseau la laisse passer.
Le WAF prend place juste après le pare-feu réseau :
Internet → pare-feu réseau (adresses, ports) → WAF (contenu HTTP) → serveur web → PHP → MySQL
Il existe sous plusieurs formes :
waf.php de la simulation.Les règles que vous avez pratiquées tout au long des modules 07 et 08 :
| Principe | Dans le code |
|---|---|
| Ne jamais faire confiance aux entrées | Valider côté serveur ce qui vient de $_GET, $_POST, $_COOKIE, des fichiers et des en-têtes |
| Séparer les données du code | Requêtes préparées (SQL), htmlspecialchars (HTML), textContent (JavaScript) |
| Moindre privilège | Un compte MySQL du site sans DROP ni GRANT, des rôles vérifiés à chaque page |
| Défense en profondeur | Pare-feu réseau, WAF, code sûr, base chiffrée : plusieurs couches indépendantes |
| Échouer en sécurité | En cas de doute, refuser. Une erreur affiche une page neutre et se lit dans le journal |
| Secrets hors du code | Mots de passe et clés dans un fichier .env hors du dossier public et hors de Git |
| Dépendances à jour | composer audit et npm audit régulièrement, mises à jour de PHP et du framework |
| Journaliser | Connexions, échecs, actions d’administration, sans jamais écrire de mot de passe |
| En-tête | Ce qu’il demande au navigateur |
|---|---|
Content-Security-Policy: default-src 'self' | N’exécuter que les scripts et styles venus du site lui-même (limite le XSS, leçon A.2) |
Strict-Transport-Security: max-age=31536000 | Toujours utiliser HTTPS pour ce site pendant un an, même si l’on tape http:// |
X-Content-Type-Options: nosniff | Respecter le type annoncé d’un fichier : un « texte » envoyé par un utilisateur n’est jamais exécuté comme script |
X-Frame-Options: DENY | Interdire l’affichage du site dans un cadre (iframe) d’un autre site, ce qui empêche le clickjacking |
Referrer-Policy: strict-origin-when-cross-origin | Ne pas transmettre l’adresse complète des pages aux autres sites |
En PHP, on les envoie avant tout affichage, une fois pour toutes dans un fichier inclus partout :
<?php
header("Content-Security-Policy: default-src 'self'");
header('Strict-Transport-Security: max-age=31536000');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('Referrer-Policy: strict-origin-when-cross-origin');
C’est la dernière leçon du module : vous savez maintenant reconnaître les principales attaques, protéger les données et configurer les défenses d’une application web. Pour vérifier un site avant sa mise en ligne, la liste de l’exercice « Le bilan avant la mise en ligne » est un bon point de départ.
Le contrôle des billets (pare-feu réseau) vérifie que vous allez au bon terminal. Le scanner des bagages (WAF) regarde ce que vous transportez. Les deux sont utiles, et aucun ne remplace l'autre.
Un cuisinier qui se lave les mains, garde le poulet cru à part et vérifie les dates n'a pas besoin d'un inspecteur pour éviter l'intoxication. Le développement sécurisé, ce sont ces gestes répétés à chaque ligne de code.
La page s'affichera ici.
Le navigateur demandera /recherche.php?q=savon au serveur, qui exécutera le PHP et renverra du HTML.
Consignes 0 / 5
Pour chaque attaque, dites quel pare-feu peut la repérer : (a) un robot qui tente le port 22 ; (b) un paramètre ?id=1 OR 1=1 ; (c) une adresse IP bannie qui revient ; (d) un champ de formulaire contenant <script>.
(a) Pare-feu réseau : il voit le port 22 et le bloque. (b) Pare-feu applicatif : le contenu de la requête HTTP (le paramètre id) n'est visible qu'en lisant HTTP. (c) Les deux savent bloquer une adresse ; le pare-feu réseau le fait le plus tôt et le moins cher. (d) Pare-feu applicatif. Et surtout le code : htmlspecialchars à l'affichage.
Écrivez une règle (expression régulière PHP) qui détecte une tentative de traversée de répertoires (../ ou ..\, y compris encodée %2e%2e%2f) dans une valeur déjà décodée par PHP.
PHP décode déjà %2e%2e%2f en ../ dans $_GET. Pensez aux deux barres, / et \.
<?php $REGLES[] = ['traversée de répertoires', '#\.\.[/\\\\]#']; // Mais la vraie protection reste dans le code : basename() et une liste de fichiers permis (leçon A.2).
Votre projet de fin de module va être mis en ligne. Listez six vérifications de sécurité à faire avant.
1. display_errors = Off en production, les erreurs vont dans un journal. 2. Les secrets (mot de passe MySQL, clés d'API) sont dans un fichier .env hors du dossier public et hors de Git. 3. Toutes les requêtes SQL sont préparées, toutes les sorties échappées. 4. Les mots de passe sont hachés avec password_hash, la connexion limite les tentatives. 5. HTTPS partout, avec les en-têtes de sécurité (HSTS, CSP, nosniff, X-Frame-Options) et des cookies Secure, HttpOnly, SameSite. 6. composer audit (ou npm audit) ne signale aucune dépendance vulnérable ; le compte MySQL du site n'a que les droits nécessaires.