Vulnérabilités des headers HTTP
Vulnérabilités de sécurité liées aux headers HTTP
Notions théoriques
Les headers HTTP sont des métadonnées envoyées avec chaque requête et réponse HTTP. Ils contiennent des informations comme le type de contenu, les paramètres de cache, l’authentification et bien plus encore. Cependant, une mauvaise configuration de ces headers peut entraîner des vulnérabilités de sécurité exploitables par des attaquants.
Headers HTTP et sécurité
Certains headers HTTP sont essentiels pour la sécurité des applications web. Voici quelques headers à bien configurer :
- Strict-Transport-Security (HSTS) : Oblige le navigateur à utiliser HTTPS, empêchant les attaques de type Man-in-the-Middle.
- X-Frame-Options : Empêche l'affichage du site dans une iframe pour éviter les attaques de Clickjacking.
- X-Content-Type-Options : Empêche le navigateur d’interpréter un fichier différemment de son type déclaré, réduisant les risques d’attaques MIME sniffing.
- Content-Security-Policy (CSP) : Définit quelles sources de contenu sont autorisées, bloquant les attaques XSS (Cross-Site Scripting).
- Referrer-Policy : Contrôle quelles informations de l’URL source sont envoyées lors d’une navigation, limitant les fuites d’informations sensibles.
Vulnérabilités liées aux headers HTTP
Une mauvaise configuration ou l'absence de ces headers peut exposer un site à des attaques :
- Sans HSTS, un attaquant peut intercepter des requêtes HTTP et injecter du contenu malveillant.
- Sans X-Frame-Options, un site peut être intégré dans une iframe malveillante pour tromper l’utilisateur et voler ses identifiants.
- Sans CSP, un attaquant peut injecter du JavaScript malveillant, modifiant le comportement du site.
- Sans X-Content-Type-Options, un fichier peut être interprété comme un script malveillant, exécuté à l’insu de l’utilisateur.
Exemple pratique
Vérifier et ajouter des headers de sécurité sur un serveur NGINX
Nous allons voir comment vérifier les headers HTTP d’un site et les configurer sur un serveur NGINX.
Étape 1 : Vérifier les headers HTTP d’un site web
Sur un terminal Linux ou Windows (PowerShell), tapez :
curl -I https://example.com
Cela affichera les headers HTTP de la réponse. Si des headers de sécurité comme X-Frame-Options
ou Content-Security-Policy
sont absents, le site est potentiellement vulnérable.
Étape 2 : Ajouter des headers de sécurité dans NGINX
Modifiez la configuration de NGINX :
server {
listen 80;
server_name example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
add_header Referrer-Policy "no-referrer";
location / {
root /var/www/html;
index index.html;
}
}
Étape 3 : Redémarrer NGINX
sudo systemctl restart nginx
Étape 4 : Vérifier que les headers sont bien appliqués
curl -I http://example.com
Les headers de sécurité devraient maintenant apparaître dans la réponse.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Objectif
Configurer un serveur NGINX sous Debian pour ajouter des headers de sécurité et tester leur efficacité depuis une machine attaquante sous Windows.
Préparation du TP
Nous allons utiliser 2 machines :
Serveur Web (Debian)
- Héberge un serveur web avec NGINX.
- Nous allons ajouter des headers de sécurité.
Attaquant (Windows)
- Enverra des requêtes HTTP pour vérifier les headers.
- Utilisera PowerShell et un navigateur pour tester la sécurité du serveur.
Installation et configuration du serveur
Étape 1 : Installer NGINX
Sur la machine Debian, ouvrez un terminal et tapez :
sudo apt update && sudo apt install nginx -y
Vérifiez que NGINX est bien installé :
nginx -v
Démarrez NGINX :
sudo systemctl start nginx
Activez NGINX pour qu’il démarre automatiquement au boot :
sudo systemctl enable nginx
Vérifiez que le serveur fonctionne en accédant à son adresse IP depuis un navigateur sur Windows :
http://<IP_DU_SERVEUR>
Si vous voyez la page par défaut de NGINX, c'est bon ! 🎉
Étape 2 : Ajouter des headers de sécurité
Modifiez la configuration du serveur pour ajouter des headers de sécurité.
Ouvrez le fichier de configuration principal de NGINX :
sudo nano /etc/nginx/sites-available/default
Ajoutez ces lignes dans le bloc server { ... }
:
server {
listen 80;
server_name _;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
add_header Referrer-Policy "no-referrer";
location / {
root /var/www/html;
index index.html;
}
}
Enregistrez et quittez (CTRL + X
, puis Y
, puis Entrée
).
Redémarrez NGINX pour appliquer les modifications :
sudo systemctl restart nginx
Tester la sécurité des headers
Étape 1 : Vérifier les headers avec PowerShell
Sur la machine Windows, ouvrez PowerShell et tapez :
Invoke-WebRequest -Uri "http://<IP_DU_SERVEUR>" -Headers @{} -UseBasicParsing | Select-Object -ExpandProperty Headers
Remplacez <IP_DU_SERVEUR>
par l'adresse IP de la machine Debian.
Vous devriez voir une réponse contenant les headers que nous avons ajoutés :
Strict-Transport-Security : max-age=31536000; includeSubDomains
X-Frame-Options : DENY
X-Content-Type-Options : nosniff
Content-Security-Policy : default-src 'self'
Referrer-Policy : no-referrer
Si certains headers sont absents, vérifiez la configuration de NGINX.
Étape 2 : Vérifier les headers avec un navigateur
- Ouvrez Google Chrome ou Firefox sur Windows.
- Allez à l’adresse
http://<IP_DU_SERVEUR>
. - Ouvrez les outils de développement (F12).
- Allez dans l’onglet "Réseau" et rechargez la page.
- Cliquez sur la requête HTTP puis vérifiez les headers dans l’onglet "Headers".
Vous devriez voir les headers de sécurité que nous avons ajoutés.
Tester une attaque simple
Nous allons maintenant simuler une attaque pour voir comment un serveur sans headers de sécurité pourrait être vulnérable.
Étape 1 : Tester une attaque Clickjacking
- Sur la machine Windows, créez un fichier HTML avec le code suivant :
<!DOCTYPE html>
<html>
<head>
<title>Test Clickjacking</title>
</head>
<body>
<iframe src="http://<IP_DU_SERVEUR>" width="800" height="600"></iframe>
</body>
</html>
- Ouvrez ce fichier dans un navigateur.
- Si le site s'affiche dans l’iframe, cela signifie que le header X-Frame-Options manque.
- Avec X-Frame-Options: DENY, le site ne devrait PAS s'afficher dans l’iframe.
Étape 2 : Tester une attaque XSS
- Sur la machine Debian, créez un fichier HTML dans
/var/www/html/
:
sudo nano /var/www/html/test.html
Ajoutez le code suivant :
<!DOCTYPE html>
<html>
<head>
<title>Test XSS</title>
</head>
<body>
<form action="#" method="GET">
<input type="text" name="q">
<input type="submit">
</form>
<script>
var urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('q')) {
document.body.innerHTML += "<p>Résultat : " + urlParams.get('q') + "</p>";
}
</script>
</body>
</html>
-
Accédez à la page depuis Windows :
http://<IP_DU_SERVEUR>/test.html
-
Testez une attaque XSS en entrant dans la barre d’adresse :
http://<IP_DU_SERVEUR>/test.html?q=<script>alert('XSS')</script>
-
Si une alerte JavaScript apparaît, cela signifie que le site est vulnérable.
-
Avec un header Content-Security-Policy bien configuré, cette attaque devrait être bloquée.
Vérification et conclusion
L'objectif de cette partie est de vérifier que les headers de sécurité sont bien configurés et de tester si les attaques sont bloquées.
Étape 1 : Vérifier les headers HTTP
Nous allons vérifier si les headers de sécurité sont bien ajoutés à la réponse HTTP du serveur.
1️⃣ Vérification avec PowerShell (Windows)
Sur la machine attaquante Windows, ouvrez PowerShell et tapez la commande suivante :
Invoke-WebRequest -Uri "http://<IP_DU_SERVEUR>" -Headers @{} -UseBasicParsing | Select-Object -ExpandProperty Headers
Résultat attendu
Vous devriez voir les headers suivants dans la réponse :
Strict-Transport-Security : max-age=31536000; includeSubDomains
X-Frame-Options : DENY
X-Content-Type-Options : nosniff
Content-Security-Policy : default-src 'self'
Referrer-Policy : no-referrer
Si l’un des headers est absent, vérifiez la configuration de NGINX sur le serveur Debian.
2️⃣ Vérification avec un navigateur (Chrome ou Firefox)
-
Ouvrez Google Chrome ou Firefox sur la machine attaquante Windows.
-
Accédez au serveur :
http://<IP_DU_SERVEUR>
-
Ouvrez les outils de développement :
- Chrome :
F12
→ Onglet "Réseau" - Firefox :
F12
→ Onglet "Réseau"
- Chrome :
-
Rechargez la page (
F5
) pour capturer la requête. -
Cliquez sur la requête HTTP et allez dans l’onglet "Headers".
-
Recherchez les headers de sécurité (
Strict-Transport-Security
,X-Frame-Options
, etc.).
Si les headers ne sont pas visibles, retournez sur le serveur Debian et vérifiez la configuration NGINX.
Étape 2 : Tester les attaques et voir si elles sont bloquées
Nous allons maintenant tester les attaques Clickjacking et XSS pour voir si les headers de sécurité fonctionnent correctement.
1️⃣ Test Clickjacking
But : Vérifier si le site peut être affiché dans une iframe (ce qui serait une faille de sécurité).
-
Sur la machine attaquante Windows, ouvrez Notepad et créez un fichier HTML :
- Enregistrez-le sous
clickjacking.html
sur le bureau.
- Enregistrez-le sous
-
Ajoutez ce code dans le fichier :
<!DOCTYPE html>
<html>
<head>
<title>Test Clickjacking</title>
</head>
<body>
<h2>Test Clickjacking</h2>
<iframe src="http://<IP_DU_SERVEUR>" width="800" height="600"></iframe>
</body>
</html>
- Ouvrez ce fichier dans un navigateur (Chrome ou Firefox).
Résultat attendu :
- Si le site s'affiche dans l'iframe, la protection X-Frame-Options ne fonctionne pas.
- Si l’iframe reste vide ou affiche une erreur, alors X-Frame-Options: DENY fonctionne correctement. ✔️
Si l’attaque fonctionne (le site s'affiche dans l’iframe), vérifiez que la ligne suivante est bien présente dans la configuration NGINX :
add_header X-Frame-Options "DENY";
Redémarrez ensuite NGINX :
sudo systemctl restart nginx
2️⃣ Test XSS (Cross-Site Scripting)
But : Vérifier si un script malveillant peut être injecté dans la page.
- Sur la machine Debian (serveur), créez un fichier HTML :
sudo nano /var/www/html/test.html
- Ajoutez ce code :
<!DOCTYPE html>
<html>
<head>
<title>Test XSS</title>
</head>
<body>
<h2>Test XSS</h2>
<form action="#" method="GET">
<input type="text" name="q">
<input type="submit">
</form>
<script>
var urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('q')) {
document.body.innerHTML += "<p>Résultat : " + urlParams.get('q') + "</p>";
}
</script>
</body>
</html>
-
Accédez à la page depuis Windows :
http://<IP_DU_SERVEUR>/test.html
-
Testez une attaque XSS en entrant cette URL dans la barre d’adresse :
http://<IP_DU_SERVEUR>/test.html?q=<script>alert('XSS')</script>
Résultat attendu :
- Si une alerte JavaScript s'affiche, le site est vulnérable. ❌
- Si l’alerte ne s’affiche pas et que le script est bloqué, la protection Content-Security-Policy fonctionne. ✔️
Si l’attaque fonctionne, vérifiez que la ligne suivante est bien présente dans la configuration NGINX :
add_header Content-Security-Policy "default-src 'self'";
Redémarrez ensuite NGINX :
sudo systemctl restart nginx
Étape 3 : Corriger la configuration si nécessaire
Si l’un des tests a échoué (Clickjacking ou XSS fonctionne), voici comment corriger les problèmes :
-
Vérifiez la configuration NGINX :
sudo nano /etc/nginx/sites-available/default
-
Ajoutez ou corrigez les headers de sécurité :
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
add_header Referrer-Policy "no-referrer"; -
Redémarrez NGINX :
sudo systemctl restart nginx
-
Refaites les tests pour vérifier que les attaques sont bloquées.