Vous devriez utiliser les en-têtes HTTP Strict Transport Security (HSTS) dans votre serveur Node.js
Raphael Mun
29 décembre 2022
0 minutes de lecturePour la plupart des sites Web et des applications, l’utilisation d’en-têtes HTTP liés à la sécurité est devenue une pratique courante. Les sites Web utilisent les en-têtes dans le cadre des requêtes et des réponses HTTP pour transmettre des informations sur une page ou sur des données envoyées via le protocole HTTP. Ils peuvent inclure un en-tête Content-Encoding pour indiquer que le contenu est un fichier zip compressé, ou un en-tête Location pour spécifier une URL de redirection.
Parmi les nombreux en-têtes de sécurité utilisés par les navigateurs Web modernes pour protéger les utilisateurs, l’en-tête HTTP Strict Transport Security (HSTS) est essentiel. L’en-tête HSTS fourni par un site Web indique au navigateur d’utiliser le protocole HTTPS lors de chaque visite ultérieure.
Pourtant, malgré leur utilité, leur facilité de mise en œuvre et leur prise en charge par pratiquement tous les navigateurs, seuls environ 25 % des réponses HTTP sur mobile et 28 % sur ordinateur incluent des en-têtes HSTS.
Examinons en détail les en-têtes HSTS pour découvrir leur impact sur la sécurité Web et comprendre pourquoi les utiliser avec Node.js. Nous verrons ensuite comment activer HSTS dans un serveur Node.js.
Pourquoi activer HSTS ?
Les connexions HTTPS sont sécurisées, car elles chiffrent et déchiffrent les paquets de données transmis à l’aide de certificats SSL/TLS, vérifiables par des autorités de certification (AC) reconnues. Ainsi, seuls l’ordinateur de l’utilisateur et le serveur peuvent lire les paquets de données transmis, quelle que soit la personne qui intercepte le trafic réseau.
Les connexions HTTP classiques ne sont pas chiffrées : toute personne qui accède aux données peut donc les lire. Parmi ces destinataires non autorisés, on peut trouver les serveurs qui acheminent et transmettent les données de l’utilisateur au serveur de destination, ou encore un pirate qui accède au trafic réseau sur un routeur Wi-Fi public.
Voici quelques conclusions du rapport Web Almanac 2022, auquel Snyk a également contribué.

À l’heure actuelle, seulement 34 % des réponses aux requêtes sur mobile et 37 % sur ordinateur incluent la directive includeSubdomain.
La majorité restante est davantage exposée aux attaques de type man-in-the-middle (MITM), qui peuvent entraîner aussi bien un vol de carte bancaire ou d’identité que la compromission des identifiants d’accès à notre application Web Node.js. Il est important de noter que les acteurs malveillants n’ont pas besoin d’intercepter les données au moment où nous saisissons nos identifiants de connexion. Les cookies du navigateur stockent et envoient souvent nos jetons de session ou d’accès, ce qui permet à ces acteurs malveillants de les obtenir par détournement de session.
Comment fonctionne HSTS ?
Lorsque l’en-tête de réponse HTTP contient un en-tête HSTS, les navigateurs Web savent qu’ils doivent toujours établir une connexion HTTPS avec le serveur et redirigent automatiquement les utilisateurs qui se sont d’abord connectés via HTTP. Dès lors, les connexions à l’application ou au site Web restent chiffrées et sécurisées, ce qui permet à l’application d’utiliser des cookies sécurisés et contribue à prévenir les attaques MITM.
L’en-tête HSTS comporte trois paramètres différents. Découvrons-les.
max - age = <expire-time>
Ce paramètre obligatoire indique, en secondes, pendant combien de temps le navigateur doit se souvenir de se connecter au site via HTTPS. Une fois ce délai écoulé, le navigateur chargera normalement le site lors de la prochaine visite. Le délai d’expiration est actualisé dans le navigateur de l’utilisateur chaque fois qu’il détecte l’en-tête HSTS. Le paramètre peut donc rester actif indéfiniment. Certains sites peuvent également désactiver immédiatement HSTS en définissant cette valeur sur 0.
Pour tester votre configuration HSTS, vous pouvez définir une durée courte, par exemple 300 secondes (cinq minutes). Une fois que vous aurez vérifié que votre site fonctionne correctement, vous pourrez la prolonger, par exemple à 31 536 000 secondes (un an).
includeSubDomains
Le paramètre includeSubDomains est une option facultative qui indique au navigateur d’activer HSTS pour le site Web et tous ses sous-domaines. Comme ce paramètre s’applique largement, vérifiez que tous vos sous-domaines prennent en charge HTTPS avant de l’activer.
preload
Une première connexion pourrait utiliser une connexion HTTP compromise. Pour y remédier, Google gère le paramètre non officiel preload. La plupart des principaux navigateurs prennent en charge cet en-tête de sécurité, qui réduit considérablement le risque. Un site Web peut ajouter le paramètre preload à l’en-tête HSTS, puis enregistrer son domaine auprès du service preload. Les navigateurs peuvent ensuite consulter cette liste de référence pour déterminer si leur première connexion peut utiliser HTTPS. Notez que le paramètre preload ne fonctionne que si vous définissez max-age sur au moins 31 536 000 secondes et activez le paramètre includeSubDomains.
Notez qu’une fois votre domaine ajouté au service preload, le traitement d’une demande de suppression peut prendre plusieurs mois. Si vous souhaitez enregistrer votre domaine pour le préchargement, prenez connaissance des conditions de soumission et des recommandations de déploiement.
Renforcer la sécurité avec HSTS
Voyons comment configurer un serveur Node.js pour qu’il renvoie un en-tête HSTS. À noter : tous les exemples de code utilisés dans cet article sont publics et disponibles dans le dépôt open source sur GitHub.
Prérequis
Ce projet nécessite les éléments suivants pour fonctionner :
Un nom de domaine enregistré
Un serveur équipé de Node.js, avec les ports réseau 80 et 433 disponibles
Un enregistrement DNS valide pour le domaine, pointant vers le serveur
Obtenir un certificat SSL/TLS
Avant d’activer HTTPS, nous avons besoin d’un certificat et d’une clé privée pour le domaine. Si vous n’en avez pas encore, vous pouvez en obtenir un auprès de Let’s Encrypt en suivant les étapes ci-dessous :
Commencez par installer certbot en suivant ces instructions. Sélectionnez autre dans le menu déroulant Logiciel, puis choisissez le système d’exploitation de votre serveur dans le menu déroulant Système. Suivez ensuite les instructions qui s’affichent.

Ensuite, vérifiez que les ports 80 et 443 sont ouverts sur le serveur, puis exécutez la commande suivante en indiquant le domaine de votre serveur :
Vous devrez peut-être précéder la commande de sudo et l’exécuter avec des privilèges élevés.

Exécutez maintenant certbot certificates (avec sudo si nécessaire) pour obtenir les chemins d’accès au certificat et à la clé privée.

Configurer le code du serveur
Commencez par créer un dossier de projet sur le serveur en exécutant la commande : mkdir snyk-demo.
Ensuite, accédez au dossier avec la commande : cd snyk-demo.
Initialisez ensuite le dossier en tant que projet Node.js avec la commande : npm init -y.

Installons maintenant les dépendances du projet pour le serveur. Suivez les instructions correspondant à Express ou Fastify.
Express :
Fastify :
Nous pouvons maintenant créer un serveur Node.js Express de base, qui gère HTTP et HTTPS.
Créez un fichier index.js dans ce dossier, puis ajoutez les modules Node suivants au début du code.
Express :
Fastify :
Ajoutez le code suivant pour charger les fichiers de certificat et remplacez la valeur de certificatePath par le chemin d’accès au certificat de votre domaine. Si vous avez utilisé certbot de LetsEncrypt, vous pouvez exécuter certbot certificates pour récupérer les chemins d’accès aux fichiers.
Express :
Fastify :
Il est maintenant temps d’initialiser l’application Express/Fastify et de créer une route de base.
Le code suivant illustre les trois paramètres HSTS, mais vous pouvez commencer par utiliser uniquement le paramètre max-age.
Option 1 : utiliser le middleware Helmet
La première méthode pour configurer HSTS consiste à utiliser le middleware Helmet lors de l’initialisation de l’application :
Express :
Fastify :
Option 2 : définir manuellement l’en-tête
Vous pouvez également définir manuellement l’en-tête HSTS au moyen d’un middleware qui l’applique à chaque réponse :
Express :
Fastify :
Pour terminer le code, créons les serveurs HTTP et HTTPS avec le code suivant :
Express :
Fastify :
Pour référence, voici les liens vers les dépôts de code des projets Express et Fastify.
Enfin, lancez le code du serveur avec node index.js, puis ouvrez votre domaine dans un navigateur Web.
Ouvrez les outils de développement de votre navigateur et examinez les en-têtes de réponse dans l’onglet Network. Vous verrez que l’en-tête HSTS est bien spécifié.

Et ensuite ?
Vous savez maintenant pourquoi les en-têtes HTTP Strict Transport Security sont importants pour la sécurité des applications Node.js, comment ils contribuent à prévenir les attaques MITM et comment les mettre en œuvre dans votre code Node.js. Vous disposez donc des outils nécessaires pour sécuriser les applications Web de vos utilisateurs.
Il vous reste un point essentiel à retenir. En environnement de production, vous ne devez pas configurer HSTS ni servir SSL depuis votre application Node.js. Vous devez plutôt confier ces tâches à des serveurs HTTP de fichiers statiques tels que NGINX ou Apache.



