Sécurisez votre site web avec les headers HTTP

La sécurité peut impliquer de lourds investissements en termes de développement web.
Mais certains petits ajustements peuvent aussi vous permettre une avancée significative en matière de sécurité. Ces modifications sont minimes en termes de code et de configuration, mais elles requièrent une bonne analyse et une validation avant d’être implémentées. Il s’agit des headers HTTP.

Plutôt que de réécrire des spécifications techniques et d’expliquer en détails le fonctionnement des headers HTTP, nous allons vous fournir une analyse synthétique et une liste de liens intéressants que vous pourrez parcourir si vous souhaitez creuser le sujet.
La première chose importante à garder à l’esprit est que ces headers ont un impact sur les navigateurs web. Ils donnent des directives aux navigateurs pour leurs comportements (s’ils implémentent les fonctionnalités correspondantes). Ils ne modifient pas le comportement du serveur web.

Nous allons présenter les headers suivants :

  • Strict-Transport-Security
  • CORS headers (Access-Control-Allow-Origin)
  • Content-Security-Policy
  • X-Content-Type-Options
  • X-XSS-Protection

Code HTML

Strict-Transport-Security

Egalement appelé HSTS (HTTP Strict Transport Security), ce header s’assure que les communications entre le navigateur web et le serveur seront bien en HTTPS.
En bref, une fois que le navigateur a reçu ce header de la part du serveur, celui-ci n’enverra plus de requêtes HTTP au serveur, mais restera sur HTTPS. Si un lien ou un contenu utilise HTTP, il sera automatiquement converti vers HTTPS.

Strict-Transport-Security: max-age=31536000

Le header ci-dessus ordonne au navigateur d’utiliser l’option STS, et de s’en rappeler pour un an.

Bien que simple à implémenter, ce header est très puissant et peut entraîner son lot de problèmes : Que se passerait-il si une partie de votre site web n’était pas accessible en HTTPS (techniquement) et si les navigateurs s’obstinaient à communiquer en HTTPS? Soyez prudent avec les options du header : vous pouvez choisir d’inclure tous les sous-domaines, mais est-ce vraiment approprié?

Du point de vue d’un attaquant :

Mettre en place ce header permet de réduire les risques liés aux attaques MITM (Man In The Middle) via lesquelles un attaquant peut voler des données sur une communication HTTP (via des attaques de type « downgrading »).
Cela permet également de couvrir le cas où un site est supposé servir tout son contenu via HTTPS et contient par erreur des liens ou contenus HTTP : les requêtes HTTP sont alors automatiquement effectuées en HTTPS.
Spécifications IETF : https://tools.ietf.org/html/rfc6797
Wikipedia : http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security

Compatibilité des navigateurs :

Internet Explorer : NON (en cours d’implémentation, prévu pour la V12)
Firefox : OUI (depuis la V4)
Chrome : OUI (depuis la V4)
Safari : OUI (depuis la V7)

Pour une liste complète des compatibilités :
http://caniuse.com/#search=strict%20transport%20security

CORS headers (Access-Control-Allow-Origin)

CORS (Cross Origin Resource Sharing) est un ensemble de règles permettant d’autoriser différents sites sur différents domaines à interagir entre eux, dans un mode normalement non autorisé par SOP (Same Origin Policy).
Pour rappel, la same origin policy a été mise en place afin d’éviter certaines problématiques de sécurité telles que des requêtes effectuées par un site malveillant (via le navigateur) sur un autre site internet, par exemple celui d’une banque, afin de récupérer le contenu d’une page du site.

Cependant, la same origin policy est très stricte et limitante dans le cas où deux sites hébergés sur des domaines différents auraient légitimement besoin de communiquer (du côté navigateur, pas du côté serveur).
La mécanique CORS a donc été introduite pour assouplir cette politique et permettre aux développeurs de spécifier quels domaines sont autorisés à effectuer des requêtes vers leur application web.

CORS inclut plusieurs headers, du côté des requêtes HTTP :
Origin
Access-Control-Request-Method
Access-Control-Request-Headers

Mais également des headers sur les réponses HTTP :
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Expose-Headers
Access-Control-Max-Age
Access-Control-Allow-Methods
Access-Control-Allow-Headers

Du point de vue d’un attaquant :

Ces headers, lorsqu’ils sont mal configurés, ouvrent des portes aux attaquants. Si une politique trop souple a été configurée (avec Access-Control-Allow-Origin: *), alors n’importe quel site web pourra récupérer le contenu d’une page sur le site ciblé. Bien entendu, ce n’est pas un problème sur des sites web contenant essentiellement des données publiques. Ces headers sont une clé pour ouvrir des portes, donc à utiliser avec précaution.

Resource W3 : http://www.w3.org/TR/cors/
Wikipedia : http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Compatibilité des navigateurs :

Internet Explorer : OUI (partiel depuis le V8, complet depuis la V10)
Firefox : OUI (depuis la V3.5)
Chrome : OUI (depuis la V4)
Safari : OUI (depuis la V4)

Pour une liste complète des compatibilités : http://caniuse.com/#search=cors

Content-Security-Policy

Contrairement à la mécanique CORS, la CSP vous permet de définir vers quels site internet votre application est autorisée à effectuer des requêtes (et donc à en récupérer du contenu).
Cette politique couvre les éléments suivants : scripts, “actions” de formulaires, frames, polices, images, feuilles de style, plugins, et medias (audio, vidéo, sous-titres…). Cette politique a été conçue afin de réduire les risques liés aux attaques de type Cross Site Scripting.

Exemple :

Content-Security-Policy:
default-src ‘self’; img-src *;
object-src media.vaadata.com;
script-src scripts.vaadata.fr

Le script ci-dessus spécifie que le site web pourra charger des images de n’importe où, que les plugins (objects) peuvent seulement être chargés depuis media.vaadata.com et que les scripts sont seulement autorisés depuis scripts.vaadata.fr

Du point de vue d’un attaquant :

Cette politique permet de réduire les risques d’attaques Cross Site Scripting (XSS), ce qui est une bonne chose pour ceux qui souhaitent défendre leurs applications (mais pas pour les attaquants!).

Resource W3 : http://www.w3.org/TR/CSP
Wikipedia : http://en.wikipedia.org/wiki/Content_Security_Policy

Compatibilité des navigateurs (version 1) :

Internet Explorer : OUI (depuis la V10 – partiel)
Firefox : OUI (depuis la V4)
Chrome : OUI (since V14)
Safari : OUI (depuis la V6)

Pour une liste complète des compatibilités : http://caniuse.com/#search=csp

X-Frame-Options

Le header X-Frame-Options est une solution anti click-jacking. Lorsqu’il est correctement configuré, ce header empêche votre site web d’être chargé à l’intérieur d’une iframe.

Note : X-Frame-Options est en train d’être intégré à CSP (1.1 et 2). CSP2 restera sur le statut de “recommandation candidate” au moins jusqu’en Juillet 2015.
En attendant, X-Frame-Options peut toujours être utilisé.

Le header accepte 3 options différents : DENY, SAMEORIGIN et ALLOW-FROM. Si vous ne souhaitez pas que votre page soit chargée dans une iframe, ni même sur votre propre domaine, utilisez simplement la directive DENY.

Exemple :

X-Frame-Options: DENY

Spécifications IETF : http://www.ietf.org/rfc/rfc7034.txt

Compatibilité des navigateurs :

Internet Explorer : OUI (depuis la V8)
Firefox : OUI (depuis la V3.6)
Chrome : OUI (depuis la V4)
Safari : OUI (depuis la V4)

La directive ALLOW-FROM n’est pas supportée par tous les navigateurs, on ne peut donc pas véritablement compter dessus.

X-Content-Type-Options

Lorsqu’il est présent, ce header demande aux navigateurs web de respecter de manière stricte les types MIME fournis par le serveur, et de ne pas deviner le type de contenu fourni. De plus les contenus ne sont acceptés que si leurs type MIME correspond à ce qui est supposé être fourni. Par exemple, une feuille de style ne sera chargée que si son type MIME correspond à “text/css”.

Laisser aux navigateurs web la possibilité de deviner la nature d’un contenu retourné par le serveur peut engendrer des problèmes de sécurité. Un attaquant peut utiliser cette vulnérabilité pour faire parvenir un contenu dangereux à vos utilisateurs. En effet, le navigateur interprète les contenus qu’il reçoit en fonction des types MIME fournis. S’il n’y en a pas ou s’il n’est pas approprié, le navigateur va décider par lui même et du code potentiellement dangereux pourra être exécuté.

C’est pour cela que les types MIME de tous les contenus retournés par votre serveur doivent être clairement définis et qu’il faut ordonner aux navigateurs de suivre le type MIME fourni. Avant d’implémenter ce header, il est important de vérifier que tous les contenus web sont servis avec le bon type MIME, afin d’éviter que des contenus soient bloqués.

Ce header est facile à implémenter, il n’accepte qu’une seule valeur : nosniff.

Compatibilité des navigateurs :

Internet Explorer : OUI (depuis la V9)
Firefox : OUI
Chrome : OUI
Safari : OUI

X-XSS-Protection

Initialement conçu par Microsoft, ce header est actuellement implémenté sur Internet Explorer et Chrome.
L’objectif, comme le nom le suggère, est de protéger les utilisateurs contre les attaques XSS.

Quelques options sont disponibles :

X-XSS-Protection 0 : Désactive la protection
X-XSS-Protection 1 : Active la protection
X-XSS-Protection 1; mode=block : Protection activée, le navigateur bloque les attaques au lieu de nettoyer le contenu.
X-XSS-Protection 1; report=http://URL-FOR-REPORT Cette option, spécifique à Chrome, va rapporter les attaques potentielles sous forme de données POST, à l’URL fournie.

Note : Ce header est désormais déprécié, et devrait être remplacé par la directive Reflected-XSS dans CSP.

Compatibilité des navigateurs :

Internet Explorer : OUI
Firefox : NON
Chrome : OUI
Safari : NON