Sécurité PHP expliquée · défensif
XSS en PHP : de quoi s’agit-il et comment s’en protéger
Le cross-site scripting reste l’un des bugs web les plus courants. En PHP, il revient presque toujours à afficher des données dans du HTML sans les échapper pour l’endroit où elles atterrissent.
Dernière mise à jour
De quoi s’agit-il
Le XSS réfléchi renvoie une valeur de la requête courante ; le XSS stocké l’enregistre, par exemple dans un commentaire, et la sert à tous ; le XSS basé sur le DOM se produit dans le JavaScript côté client. Dans tous les cas, le navigateur exécute un script avec les droits de votre site, ce qui permet de voler des sessions ou d’agir au nom de l’utilisateur. MITRE le classe en CWE-79.
Comment le détecter
- Cherchez dans les templates et fichiers PHP les
echo,printet<?=qui affichent des variables sanshtmlspecialchars()ni filtre d’échappement. - Soyez attentif aux valeurs placées dans des attributs HTML, du JavaScript en ligne, des URL et du CSS, où l’échappement HTML seul ne suffit pas.
- Utilisez les contrôles de sécurité de votre framework et un scanner comme OWASP ZAP sur une copie de préproduction qui vous appartient.
Comment le corriger
- Échappez à la sortie :
htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8')pour le corps HTML et les attributs entre guillemets. - Utilisez un moteur de templates avec échappement automatique (Twig, Blade, Latte) et évitez les filtres de sortie brute pour les données non fiables.
- Utilisez
json_encode()avecJSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOTpour les données dans les blocs script, et validez les URL avant de les mettre dans href. - Ajoutez une Content-Security-Policy et marquez les cookies de session HttpOnly, Secure et SameSite.
Vérifications en lecture seule et modèles sûrs
# Find raw echo of request data (read-only, rough first pass)
grep -rnE "echo\s+\$_(GET|POST|REQUEST|COOKIE)" --include=*.php . | grep -v /vendor/
// Escape on output, for the HTML context
echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
# Defense in depth: a Content-Security-Policy header (example)
Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'Faut-il plutôt retirer les balises en entrée ?
Filtrer l’entrée aide, mais c’est l’échappement à la sortie selon le contexte qui empêche le XSS de façon fiable. L’OWASP recommande d’abord l’encodage en sortie.
strip_tags() empêche-t-il le XSS ?
Pas de façon fiable. Il ne gère pas les contextes d’attribut ou JavaScript et s’utilise facilement mal.
Autres classes de vulnérabilités PHP
- Injection d’objets PHP : de quoi s’agit-il et comment corrigerL’injection d’objets PHP survient quand une entrée contrôlée par l’utilisateur atteint unserialize(), qui peut instancier des objets dont les méthodes magiques exécutent une logique choisie par l’attaquant.
- Inclusion de fichiers PHP (LFI/RFI) : de quoi s’agit-il et comment corrigerL’inclusion de fichiers survient quand une entrée utilisateur contrôle le chemin passé à include ou require, ce qui permet de lire des fichiers locaux (LFI) ou, avec allow_url_include activé, d’exécuter du code distant (RFI).
- SSRF en PHP : de quoi s’agit-il et comment corrigerLa falsification de requête côté serveur (SSRF) survient quand une application PHP récupère une URL contrôlée par l’utilisateur, ce qui permet d’atteindre des services internes ou des points de métadonnées cloud via votre serveur.
- Exposition de phpinfo() : pourquoi c’est important et comment corrigerUne page phpinfo() publique révèle la version exacte de PHP, les modules chargés, les chemins et souvent des variables d’environnement ou des secrets, ce qui aide les attaquants à cibler des failles comme PHP2Shell.
Sources
Les liens externes quittent ce site. Nous n’hébergeons aucun code d’exploitation.
- CWE-79: Cross-site Scripting — MITRE CWE
- Cross Site Scripting Prevention Cheat Sheet — OWASP Cheat Sheet Series
- htmlspecialchars() — PHP Manual