Les principaux en-têtes HTTP de sécurité
Introduction
Les en-têtes HTTP de sécurité sont des en-têtes de réponse envoyés par le serveur web. Ils indiquent au navigateur de traiter de façon spécifique certains aspects de sécurité pouvant impacter l’application web ou l’utilisateur lors de sa navigation. L’absence d’un ou de plusieurs de ces en-têtes, n’est généralement pas une vulnérabilité en soi, mais leurs présences constituent une défense en profondeur permettant de limiter ou de ralentir certaines attaques.
Il existe un nombre important d’en-têtes liés à la sécurité des applications web, mais tous ne sont pas forcément à appliquer suivant le contexte et l’écosystème. Certains ne sont que très rarement utilisés, car leur mise en place est spécifique à certains navigateurs devenus maintenant obsolètes. D’autres sont expérimentaux, et ne sont pas encore complètement pris en charge par tous les navigateurs récents.
La fondation Mozilla met à disposition un guide de référence, disponible à l’adresse https://infosec.mozilla.org/guidelines/web_security, à destination des équipes opérationnelles afin d’aider à la priorisation de certains aspects de la sécurité web....
Vérifier la présence d’un en-tête HTTP
La vérification de la présence de ces en-têtes peut se faire directement en analysant une réponse HTTP en utilisant un proxy web tel que Burp. L’exemple ci-dessous est une réponse contenant tous les en-têtes HTTP renvoyés par le serveur lors d’une navigation :
Ces informations sont visibles dans l’onglet HTTP history, mais aussi suite à l’utilisation du Repeater ou de l’Intruder de Burp. Il est également possible d’utiliser les outils de développement intégrés aux différents navigateurs, ici par la visualisation de l’onglet Network du navigateur Google Chrome :
Dans certains cas, ce sont les clients ou les prestataires de l’entreprise eux-mêmes, surtout dans un cadre B2B, qui effectueront ces vérifications, avec ou sans le consentement du propriétaire de l’application. Lorsqu’un client ou prestataire utilise une solution SaaS, il n’est pas rare qu’il souhaite évaluer la sécurité de la plateforme avant de l’utiliser. En général, il utilisera un outil clé en main pour vérifier la présence des en-têtes HTTP de sécurité, et n’hésitera pas à communiquer les résultats au propriétaire de l’application. Certains...
Mise en place d’un en-tête HTTP de sécurité
La mise en place d’un en-tête de sécurité s’effectue généralement par la modification des fichiers de configuration du serveur web de l’application.
1. Serveur web Apache
Pour Apache, il faut tout d’abord activer le module headers, en utilisant la commande a2enmod :
$ sudo a2enmod headers
Enabling module headers.
To activate the new configuration, you need to run:
systemctl restart apache2
Puis, dans le fichier /etc/apache2/sites-available/000-default.conf (dans le cadre d’une configuration par défaut), ajouter la ligne pour l’en-tête désiré avec la syntaxe suivante :
Header set nom_en-tête: "directive(s)"
Il ne reste plus qu’à redémarrer le serveur afin que les modifications soient prises en compte :
$ sudo systemctl restart apache2
2. Serveur web Nginx
Pour Nginx, il suffit d’ajouter la directive suivante dans le fichier de configuration, par défaut /etc/nginx/sites-available/000-default.conf :
add_header nom_en-tête "directives";
Un redémarrage du serveur est nécessaire afin que les modifications soient prises en compte :
$ sudo systemctl restart nginx
Il existe plusieurs autres méthodes permettant de mettre en place la plupart des en-têtes HTTP, telles que l’utilisation...
HTTP Strict Transport Security Header
L’en-tête HTTP Strict Transport Security (HSTS) concerne la sécurité de la transmission des données entre le navigateur et l’application web. En général, cette protection est assurée par la mise en place du protocole de sécurité Transport Layer Security (TLS) qui permet une communication sécurisée via HTTPS. Cependant, malgré cette protection, des faiblesses peuvent subsister. L’utilisation de l’en-tête HSTS vise à remédier à certaines de ces vulnérabilités.
1. HTTP contre HTTPS
Une communication s’effectuant sur le protocole HyperText Transfer Protocol (HTTP) n’est pas sécurisée et va permettre facilement à un attaquant d’écouter ou de modifier le trafic entre sa victime et l’application web vulnérable. Pour ces raisons, l’utilisation du protocole HyperText Transfer Protocol Secure (HTTPS) est nécessaire.
Par défaut, le protocole HTTP fonctionne sur le port 80 et sa version sécurisée sur le port 443. Ils peuvent être atteints en spécifiant le protocole au début de l’URL, par exemple : http://example.com (version non sécurisée) ou https://example.com (version sécurisée). Sous Firefox, l’accès à une URL en HTTP est visible grâce à l’affichage d’un pictogramme représentant un cadenas barré dans la barre d’adresse, tandis que l’accès à une URL sécurisée se voit doté d’un cadenas fermé :
|
|
Mais pourquoi un utilisateur renseignerait-il une URL avec le protocole HTTP et non HTTPS ? Il existe plusieurs cas où cela peut arriver :
-
L’utilisateur n’est pas sensibilisé à la sécurité et renseigne http:// dans sa barre d’adresse lorsqu’il tente d’accéder à un site web.
-
L’utilisateur suit un lien commençant par http:// lors de sa navigation sur un site (forum, etc.), ou qu’une personne lui a fourni par messagerie instantanée, courrier électronique, SMS.
-
L’utilisateur a enregistré en favori une telle URL afin d’y accéder plus facilement plus tard.
2. Redirection des utilisateurs...
X-Frame-Options
X-Frame-Options (également appelé XFO) est un en-tête de réponse HTTP qui permet d’indiquer au navigateur si l’affichage de la page est autorisé lorsqu’elle est appelée depuis un contexte de navigation embarqué (soit les éléments HTML <frame>, <iframe>, <embed> ou <object>). Il permet de protéger les visiteurs de la vulnérabilité nommée clickjacking (détournement de clics).
Cette vulnérabilité est traitée au sein du chapitre Autres vulnérabilités applicatives.
Bien que présent dans la liste des en-têtes attendus par des outils tels que Mozilla Observatory, l’en-tête X-Frame-Options est un en-tête supplanté par l’ensemble des politiques Content Security Policy (CSP), et plus précisément par la directive nommée frame-ancestors. De plus, seul Internet Explorer 8+, dont le développement de la dernière version a été arrêté en juin 2022, et quelques autres anciennes versions de navigateurs, telles que Edge ou Firefox, implémentent complètement cette fonctionnalité :
Généralement, la présence de l’en-tête X-Frame-Options n’est réellement utile que si la réponse contient des éléments permettant...
X-Content-Type-Options
1. Le type MIME
Le type MIME (Multipurpose Internet Mail Extensions) est un standard défini par la RFC 2046 (https://datatracker.ietf.org/doc/html/rfc2046), proposé par les laboratoires Bell afin de permettre d’insérer des documents dans les courriers électroniques. Le standard a ensuite évolué afin de fonctionner sur le protocole HTTP. Cette évolution est décrite dans la RFC 6838 (https://datatracker.ietf.org/doc/html/rfc6838).
Le type MIME est un identifiant en deux parties, un type et un sous-type, accompagné d’éventuelles options. Il permet de spécifier le type du document à échanger : une image, un document audio ou vidéo, ou encore un simple texte. Les options permettent de spécifier certaines informations additionnelles comme le jeu de caractères du document.
Sa syntaxe est la suivante :
Type/sous-type; options
Voici quelques exemples pouvant être présents dans les échanges HTTP :
-
text/plain
-
text/html
-
image/png
-
application/octet-stream
-
application/json; charset=utf-8
Le type MIME text/plain est la valeur par défaut pour les fichiers texte. En général, un navigateur tentera d’afficher un tel fichier. Au contraire, le type MIME application/octet-stream est la valeur par défaut pour un fichier binaire. En temps normal, un fichier ayant ce type MIME ne sera pas exécuté au sein du navigateur, mais plutôt proposé en téléchargement.
2. L’en-tête HTTP Content-Type
Lorsque le navigateur reçoit la réponse du serveur HTTP, il doit déterminer la façon de la traiter. Doit-il simplement afficher le document comme étant du texte brut ? Doit-il l’interpréter et exécuter le code présent, ou le proposer au téléchargement à l’utilisateur ?
Pour répondre à cette question, le navigateur va se reposer sur la valeur de l’en-tête nommé Content-Type, présent dans la réponse HTTP, qui spécifie le type MIME du document. Ainsi le navigateur sera en mesure de décider quelle action prendre. Voici un exemple pour un document HTML indiquant donc au navigateur d’en effectuer le rendu :
HTTP/1.1 200 OK
Content-Type: text/html;...
Referrer-Policy
Avant d’aborder l’en-tête de sécurité Referrer-Policy, il est essentiel de comprendre l’en-tête Referer et son rôle dans les requêtes HTTP. L’en-tête Referer est un en-tête présent dans les requêtes HTTP et qui a comme valeur l’adresse de la page web depuis laquelle le lien a été joué pour accéder à la page courante. La requête permettant d’accéder à la page https://eni.fr à partir des résultats d’une recherche Google possédera, par exemple, l’en-tête HTTP Referer avec comme valeur https://google.fr :
GET / HTTP/1.1
Host: www.eni.fr
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
image/avif,image/webp,image/apng,*/*;q=0.8,application/
signed-exchange;v=b3;q=0.7
Referer: https://www.google.fr/
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
Les propriétaires de sites web utilisent ces informations à des fins de statistiques ou de journalisation. Cet en-tête est présent dans la plupart des cas sauf dans les situations suivantes :
-
L’origine utilise le protocole HTTPS mais le lien à suivre pointe...
X-XSS-Protection
X-XSS-Protection est un en-tête HTTP de sécurité qui est maintenant déprécié. Malgré cela, il reste toutefois très présent dans les résultats de scanner web. Plus aucun navigateur récent ne le supporte dorénavant :
Cette fonctionnalité était censée protéger contre les injections XSS de type réfléchi en assainissant ou en arrêtant le chargement de la page lorsqu’une telle attaque est détectée. Mais cette protection était loin d’être suffisante et pouvait même, dans certains cas, introduire des vulnérabilités XSS.
L’OWASP recommande plutôt d’implémenter une politique CSP forte et de ne pas ajouter l’en-tête X-XSS-Protection. Mais certains scanners remontent toujours son absence comme un problème de sécurité en raison de la protection des vieux navigateurs (https://observatory.mozilla.org/faq/) :
L’OWASP recommande autrement de désactiver manuellement cette protection grâce à la valeur 0, mais encore une fois certains scanners peuvent poser problème :
Syntaxe
La syntaxe de l’en-tête X-XSS-Protection est la suivante :
X-XSS-Protection: directive
Directives
0
Désactive le filtre anti-XSS.
1
Active le filtre anti-XSS. Si une attaque...
Content Security Policy
Content Security Policy (CSP) est un mécanisme de sécurité permettant une défense en profondeur de la partie cliente. Cette politique se base sur un ensemble de règles aidant à protéger contre certains types d’attaques tels que le Cross-Site Scripting (XSS) ou le clickjacking. La version actuelle est la version 2 (https://www.w3.org/TR/CSP2/) et une version 3 est en cours d’élaboration (https://www.w3.org/TR/CSP3/) mais déjà supportée partiellement par les navigateurs récents. L’activation de la politique s’effectue grâce à la mise en place de l’en-tête de réponse HTTP Content-Security-Policy.
Syntaxe
La syntaxe de l’en-tête, dont les différentes directives sont séparées par le caractère « ; », est la suivante :
Content-Security-Policy : directives
Étant donné le nombre de directives existantes, elles ne seront pas toutes détaillées dans ce chapitre mais plusieurs exemples seront donnés.
Une directive peut contenir une source-list, il s’agit d’une chaîne de caractères composée d’un ou plusieurs éléments :
-
’none’ : indique qu’aucune ressource ne peut être chargée depuis aucune source.
-
’self’ : indique que les ressources ne peuvent être chargées seulement depuis la même origine que le document.
-
schéma : tous les schémas autorisés, notamment par la RFC3986 (par exemple http: ou https:, data:, ws:, etc).
-
hôte : nom d’hôte sous la forme d’un nom ou d’une adresse IP (IPv4 ou IPv6). Le schéma, le numéro de port et les chemins sont optionnels.
-
’unsafe-eval’ : autorise l’évaluation de code JavaScript par la méthode eval().
-
’unsafe-inline’ : autorise l’exécution de script de type inline.
-
’unsafe-hashes’ : autorise seulement les évènements (events handler) mais pas les éléments de script ni les URL javascript:.
-
nonce-value : autorise seulement les scripts possédant le nonce spécifié par la politique. Le nonce doit être regénéré...
Cross-Origin Resource Sharing
La politique de même origine (Same-Origin Policy, SOP), interdit, ou du moins régule, les communications entre plusieurs domaines. Cependant, les exigences et les usages du web évoluent, entraînant une croissance de la nécessité de partager des informations. Le JSONP (JSON with Padding) est une technique JavaScript proposée en 2005 par Bob Ippolito qui permet de contourner la politique de même origine, afin d’établir une telle communication inter-domaines (cross-origin). Néanmoins, elle possède des faiblesses inhérentes à son fonctionnement, et n’est définie par aucun standard officiel. Bien que toujours utilisée, cette technique est obsolète et remplacée par le mécanisme de Cross-Origin Resource Sharing (CORS) depuis 2009.
L’implémentation du mécanisme CORS est nécessaire seulement lors de l’utilisation de communication interdomaines.
1. Fonctionnement
CORS est un mécanisme qui permet à un serveur d’ajouter un ensemble d’en-têtes HTTP spécifiques, afin d’autoriser le navigateur d’accéder à des ressources situées en dehors du domaine actuel. Il permet ainsi d’étendre les possibilités de communication cross-origin, tout en maintenant un contrôle sur les interactions autorisées. Il est possible de séparer les différents types de requêtes en deux groupes distincts : les requêtes simples et les requêtes déclenchant des requêtes préliminaires d’autorisation, nommées preflight requests.
a. Requêtes simples
Les requêtes simples englobent l’utilisation des méthodes HTTP HEAD, GET, et POST, dont ce dernier est limité à l’ensemble de valeurs d’en-tête Content-Type suivant :
-
text/plain
-
application/x-www-form-urlencoded
-
multipart/form-data
De plus, dans ce contexte de requêtes simples, seul un ensemble déterminé d’en-têtes HTTP client est permis (en plus des en-têtes envoyés automatiquement par le navigateur, tels que l’en-tête User-Agent, par exemple) :
-
Accept
-
Accept-Language
-
Content-Language
Les requêtes possédant un en-tête HTTP personnalisé...