Skip to Content
SecurityHeaders HTTP sécurisés

Headers HTTP sécurisés

Configuration des en-têtes HTTP pour protéger les applications web contre les attaques courantes (XSS, clickjacking, MIME sniffing, etc.).

Vue d’ensemble

En-têteProtectionValeur recommandée
Content-Security-PolicyXSS, injectionPolitique restrictive adaptée à l’appli
X-Frame-OptionsClickjackingDENY ou SAMEORIGIN
X-Content-Type-OptionsMIME sniffingnosniff
Referrer-PolicyFuites de donnéesstrict-origin-when-cross-origin
Permissions-PolicyContrôle des APIs navigateurRestrictions au besoin

Ces en-têtes sont applicatifs (gérés côté serveur ou via un middleware). Pour la génération de secrets en ligne de commande, voir CLI Security.

Helmet (Node.js / Express)

Helmet est le package standard pour définir les headers de sécurité dans une application Express.

npm install helmet
const express = require('express'); const helmet = require('helmet'); const app = express(); // Applique tous les headers recommandés par défaut app.use(helmet()); // Configuration personnalisée — activer les headers un par un app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:", "https:"], } }, xFrameOptions: { action: 'deny' }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true } }));

CORS — Contrôle d’accès inter-origines

Configurez CORS uniquement pour les origines connues. Ne jamais utiliser Access-Control-Allow-Origin: * en production.

const cors = require('cors'); app.use(cors({ origin: ['https://mon-domaine.com', 'https://app.mon-domaine.com'], methods: ['GET', 'POST'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true }));

En-tête manuel (sans middleware)

app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'https://mon-domaine.com'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.setHeader('Access-Control-Allow-Credentials', 'true'); next(); });

Content-Security-Policy (CSP)

La CSP est l’en-tête le plus puissant contre les XSS. Elle doit être progressive : commencer large, puis resserrer.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com; frame-ancestors 'none'

Directives essentielles

DirectiveUsage
default-srcPolitique par défaut (applique si aucune directive spécifique ne correspond)
script-srcSources autorisées pour les scripts
style-srcSources autorisées pour les feuilles de style
img-srcSources autorisées pour les images
connect-srcSources autorisées pour XHR, fetch, WebSocket
frame-ancestorsOrigines autorisées à intégrer la page via iframe
report-uriEndpoint de rapport des violations

Ne jamais utiliser 'unsafe-inline' pour script-src en production si possible. Cela annule la protection CSP contre les XSS par injection de scripts.

X-Frame-Options

Empêche le clickjacking en interdisant l’intégration de la page dans un iframe depuis un autre domaine.

// Via Helmet app.use(helmet({ xFrameOptions: { action: 'deny' } })); // Manuel res.setHeader('X-Frame-Options', 'DENY');
ValeurComportement
DENYAucune iframe, même sur le même domaine
SAMEORIGINiframe autorisé uniquement depuis le même domaine
ALLOW-FROM uriDéprécié, à remplacer par Permissions-Policy

X-Content-Type-Options

Empêche le navigateur d’interpréter un fichier comme un type de contenu différent de celui annoncé.

res.setHeader('X-Content-Type-Options', 'nosniff');

Sans cet en-tête, un navigateur peut exécuter un fichier .js servi avec le Content-Type: text/plain, ou inversément.

Cookies sécurisés

Les cookies contiennent souvent des tokens de session. Ils doivent être protégés au niveau des attributs.

res.cookie('session', token, { httpOnly: true, // inaccessible au JavaScript côté client secure: true, // envoyé uniquement via HTTPS sameSite: 'strict', // empêche l'envoi lors de requêtes cross-site maxAge: 3600000 // expiration en millisecondes });
AttributProtection
HttpOnlyLe cookie n’est pas lisible via document.cookie
SecureLe cookie n’est envoyé que sur les connexions HTTPS
SameSite=StrictLe cookie n’est jamais envoyé lors d’une requête cross-site
SameSite=LaxEnvoyé uniquement lors d’une navigation globale (GET, lien)

Referrer-Policy

Contrôle quelles informations d’URL sont transmises dans l’en-tête Referer.

res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
PolitiqueComportement
no-referrerAucun en-tête Referer
originSeule l’origine est transmise
strict-origin-when-cross-originURL complète sur même origine, uniquement l’origine sur cross-origin
no-referrer-when-downgradeURLs complètes, sauf si HTTPS → HTTP

Permissions-Policy

Contrôle quelles fonctionnalités du navigateur une page peut utiliser.

res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');

Vérification en production

# Vérifier les headers retournés par un serveur curl -I https://mon-domaine.com # Sortie attendue (extraits) : # Content-Security-Policy: ... # X-Frame-Options: DENY # X-Content-Type-Options: nosniff # Strict-Transport-Security: max-age=31536000; includeSubDomains; preload # Referrer-Policy: strict-origin-when-cross-origin

Checklist de déploiement

  • Helmet ou middleware équivalent installé et activé
  • CORS configuré avec origines explicites (pas de * en production)
  • CSP définie et testée (utiliser report-uri pour détecter les violations avant de passer en mode bloqueur)
  • X-Frame-Options: DENY ou SAMEORIGIN appliqué
  • X-Content-Type-Options: nosniff activé
  • Cookies avec HttpOnly, Secure, SameSite
  • Referrer-Policy défini
  • HTTPS forcé (redirection HTTP → HTTPS)
  • Strict-Transport-Security avec preload activé