← Cybersécurité

XSS et sécurisation des sessions

Sommaire

Défi n°3 du TP Cyber-Rescue : une faille XSS sur le forum, et la sécurisation des cookies de session qui va avec.

1. Mise en évidence

Publier ce message sur le forum :

<script>alert("XSS - Ton cookie : " + document.cookie);</script>

Si une boîte de dialogue s'ouvre en affichant le cookie, l'application est vulnérable : le contenu saisi par un utilisateur est renvoyé tel quel dans la page, et le navigateur l'interprète comme du code plutôt que comme du texte.

La démonstration semble anodine, l'exploitation ne l'est pas : le même script peut envoyer le cookie de session vers un serveur contrôlé par l'attaquant, qui rejoue alors la session sans jamais connaître le mot de passe.

2. Types de XSS

TypeOù vit la chargeDéclenchementPortée
Stockée (persistante) Enregistrée en base (message de forum, commentaire, profil) À chaque affichage de la page par n'importe quel visiteur La plus grave : touche tous les utilisateurs, dont les administrateurs
Réfléchie Dans l'URL, renvoyée immédiatement dans la réponse Uniquement si la victime ouvre le lien piégé Ciblée, nécessite une phase d'ingénierie sociale
DOM Côté client, dans du JavaScript qui manipule le DOM Sans passage par le serveur Invisible dans les journaux serveur

3. Échapper en sortie

Partout où l'on affiche du contenu utilisateur :

<?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?>

La fonction convertit les caractères structurants du HTML en entités : < devient &lt;, > devient &gt;, " et ' deviennent leurs entités respectives grâce à ENT_QUOTES. Le navigateur affiche alors littéralement <script> au lieu de l'exécuter.

4. Cookies de session

<?php
session_set_cookie_params([
    'lifetime' => 1800,
    'path'     => '/',
    'domain'   => '',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Strict',
]);
session_start();
AttributEffetAttaque contrée
secure Le cookie n'est transmis que sur une connexion HTTPS Interception en clair sur le réseau (session sidejacking, Wi-Fi ouvert)
httponly Le cookie est inaccessible à document.cookie Vol de session par XSS : même en cas de faille, le script ne lit pas le cookie
samesite=Strict Le cookie n'est pas envoyé lors d'une requête initiée par un autre site CSRF : action déclenchée à l'insu de l'utilisateur depuis un site tiers
lifetime Durée de vie limitée du cookie Réduit la fenêtre d'exploitation d'une session abandonnée

En TP sur HTTP, secure => true empêche toute connexion : le navigateur refuse d'envoyer le cookie. On le laisse à false pendant l'exercice, et l'on note que le passage en production impose HTTPS et ce paramètre. C'est une limite du laboratoire, pas une recommandation.

httponly et l'échappement en sortie sont complémentaires : le premier limite l'impact d'une XSS, le second l'empêche. On applique les deux — défense en profondeur.

5. Aller plus loin : Content Security Policy

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'

L'en-tête CSP indique au navigateur quelles sources de scripts sont légitimes. Une charge XSS injectée en ligne n'est alors pas exécutée, même si l'échappement a été oublié quelque part. C'est un filet de sécurité, jamais un substitut à l'échappement.