← Journal technique

security

Helmet, et la CSP qu'on laisse généralement à ne rien faire

Helmet, et la CSP qu'on laisse généralement à ne rien faire

Helmet pose un paquet d'en-têtes de réponse HTTP que les navigateurs utilisent pour faire respecter des politiques de sécurité. Il ne fait rien d'actif — il dit au navigateur de se comporter plus strictement avec cette réponse, et le navigateur le fait respecter côté client.

import helmet from "helmet";
app.use(helmet());

Ce que font les en-têtes :

  • Strict-Transport-Security — ne te connecte plus qu'en HTTPS pour ce domaine désormais, même si un utilisateur tape http://. Bloque les attaques de rétrogradation.
  • X-Content-Type-Options: nosniff — empêche le navigateur de deviner le type d'un fichier et de l'exécuter comme autre chose que son Content-Type déclaré. C'est le cas où une « image » uploadée se fait exécuter comme un script.
  • X-Frame-Options / CSP frame-ancestors — contrôle si le site peut être intégré dans une iframe ailleurs. Empêche le clickjacking.
  • Content-Security-Policy — le gros morceau. Une liste blanche d'où peuvent se charger scripts, styles, images et polices. Bien configurée, c'est une forte défense contre le XSS même si un attaquant injecte une balise <script> — le navigateur refuse de l'exécuter si la source n'est pas autorisée.
  • Referrer-Policy — combien de l'URL courante fuit vers le site suivant sur un clic sortant.

Ça compte pour une API NestJS même si Helmet est généralement décrit pour des pages rendues dans le navigateur, parce que les réponses de l'API sont quand même lues dans un contexte navigateur via fetch, et les en-têtes comptent quand même pour tout HTML que l'API pourrait servir — pages d'erreur, docs, une interface de health check — plus un HSTS cohérent sur tout le domaine.

helmet() sans config est un début raisonnable, pas la fin. La CSP en particulier a généralement besoin de réglages personnalisés — le défaut est assez strict et cassera les scripts inline, les embeds tiers ou les polices de CDN à moins qu'ils ne soient explicitement en liste d'autorisation. L'erreur Helmet la plus courante est une CSP laissée si lâche qu'elle ne fait rien, ou si stricte qu'elle casse l'application et se fait désactiver entièrement au lieu d'être corrigée. (J'ai été des deux côtés de ça. Ma pire version était une CSP uniquement en production qui bloquait silencieusement le visualiseur de PDF et le reporting d'erreurs — invisible en local, et elle n'a jamais fait échouer un test.)