Explorer
KNOW-PAT-223

Security Headers & CSP — Configuration des headers HTTP de sécurité

Domaine
cybersecu
Type
pattern
Priorité
P1

Security Headers & CSP

Problème

Les applications web sont vulnérables au XSS, clickjacking, MIME sniffing et downgrade attacks faute de headers de sécurité.

Solution

Defense-in-depth via HTTP response headers. Une structure "safe even if you slip" plutôt que "dangerous if you slip".

Headers obligatoires

HSTS (HTTP Strict Transport Security)

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • Force HTTPS, empêche downgrade attacks
  • preload pour soumission à la HSTS preload list

CSP (Content-Security-Policy)

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{RANDOM}'; style-src 'self' 'nonce-{RANDOM}'; img-src 'self' data: https:; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
  • default-src 'self' — deny by default
  • nonce-{RANDOM} — autorise seulement les scripts avec le nonce (généré par request)
  • frame-ancestors 'none' — empêche clickjacking (remplace X-Frame-Options)
  • Pas de 'unsafe-inline' ni 'unsafe-eval'

Autres headers

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin

Implementation Express.js (Helmet)

const helmet = require('helmet');

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", 'nonce-{RANDOM}'],
      styleSrc: ["'self'", 'nonce-{RANDOM}'],
      imgSrc: ["'self'", 'data:', 'https:'],
      connectSrc: ["'self'", 'https://api.example.com'],
      frameAncestors: ["'none'"],
      baseUri: ["'self'"],
      formAction: ["'self'"]
    }
  },
  strictTransportSecurity: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  }
}));

Implementation Next.js

// next.config.js
const cspHeader = `
  default-src 'self';
  script-src 'self' 'nonce-${nonce}';
  style-src 'self' 'nonce-${nonce}';
  img-src 'self' data: https:;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';
`

module.exports = {
  async headers() {
    return [{
      source: '/(.*)',
      headers: [
        { key: 'Content-Security-Policy', value: cspHeader },
        { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains; preload' },
        { key: 'X-Content-Type-Options', value: 'nosniff' },
        { key: 'X-Frame-Options', value: 'DENY' },
        { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
        { key: 'Permissions-Policy', value: 'geolocation=(), microphone=(), camera=()' }
      ]
    }]
  }
}

Vérification

Références

  • [[KNOW-REF-043]] — OWASP ASVS V13 (security headers)
  • [[KNOW-REF-044]] — OWASP Proactive Controls C8
  • [[KNOW-PAT-220]] — Secure SDLC Checklist