Déjouer les intermédiaires malveillants avec HTTPS et HTTP Strict Transport Security

Compte tenu de la quantité de données à caractère personnel qui transite par la grande série de tuyaux qu'est Internet, le chiffrement n'est pas quelque chose que nous pouvons ou devrions ignorer. Les navigateurs modernes proposent plusieurs mécanismes que vous pouvez utiliser pour vous assurer que les données de vos utilisateurs sont sécurisées pendant leur transfert: les cookies sécurisés et la sécurité du transport stricte sont deux des plus importants. Ils vous permettent de protéger facilement vos utilisateurs, de mettre à niveau leurs connexions vers HTTPS et de garantir que les données utilisateur ne sont jamais envoyées en clair.

En quoi cela vous concerne-t-il ? Réfléchissez aux points suivants:

Diffuser une page Web via une connexion HTTP non chiffrée revient plus ou moins à remettre une enveloppe non scellée à la première personne que vous voyez dans la rue qui semble se diriger vers le bureau de poste. Si vous avez de la chance, elle peut vous emmener jusqu'à destination elle-même ou vous la remettre à la première personne qu'elle voit qui va dans la bonne direction. Cette personne peut faire de même, et ainsi de suite.

La plupart des inconnus de cette chaîne impromptue sont fiables et ne jetteront jamais un coup d'œil à votre lettre ouverte ni ne la modifieront. Cependant, plus la lettre change de mains, plus le nombre de personnes ayant un accès complet à la lettre que vous envoyez augmente. En fin de compte, il est fort probable que le destinataire prévu de votre lettre reçoive quelque chose par la poste, mais il est difficile de savoir si cet élément est le même que celui que vous avez remis au départ. Peut-être auriez-vous dû fermer cette enveloppe ?

Intermédiaires

Pour le meilleur ou pour le pire, de vastes pans d'Internet reposent sur la fiabilité d'étrangers. Les serveurs ne sont pas directement connectés les uns aux autres, mais transmettent les requêtes et les réponses de routeur à routeur dans un énorme jeu de téléphone.

Vous pouvez voir ces sauts en action avec traceroute. L'itinéraire de mon ordinateur vers HTML5Rocks se présente comme suit:

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

13 sauts, ce n'est pas si mal. Toutefois, si j'envoie des requêtes via HTTP, chacun de ces routeurs intermédiaires a un accès complet à mes requêtes et aux réponses des serveurs. Toutes les données sont transférées en texte brut non chiffré, et n'importe lequel de ces intermédiaires peut agir en tant qu'homme au milieu, en lisant mes données ou même en les manipulant pendant leur transfert.

Pire encore, ce type d'interception est pratiquement indétectable. Une réponse HTTP modifiée de manière malveillante ressemble exactement à une réponse valide, car aucun mécanisme ne permet de s'assurer que les données reçues correspondent _exactement_ aux données envoyées. Si quelqu'un décide de me faire perdre la connexion Internet pour rigoler, je n'ai pas grand-chose à faire.

S'agit-il d'une ligne sécurisée ?

Passer du protocole HTTP en texte brut à une connexion HTTPS sécurisée constitue la meilleure défense contre les intermédiaires. Les connexions HTTPS chiffrent l'intégralité du canal de bout en bout avant l'envoi de données, ce qui empêche les machines situées entre vous et votre destination de lire ou de modifier les données en transit.

L'omnibox de Chrome fournit de nombreux détails sur l'état d'une connexion.
L'Omnibox de Chrome fournit de nombreuses informations sur l'état d'une connexion.

La sécurité fournie par HTTPS repose sur le concept de clés cryptographiques publiques et privées. Une discussion approfondie des détails dépasse (heureusement) le cadre de cet article, mais la prémisse de base est assez simple: les données chiffrées avec une clé publique donnée ne peuvent que être déchiffrées avec la clé privée correspondante. Lorsqu'un navigateur lance un handshake HTTPS pour créer un canal sécurisé, le serveur fournit un certificat qui fournit au navigateur toutes les informations nécessaires pour vérifier son identité en vérifiant que le serveur est en possession de la clé privée appropriée. À partir de ce moment-là, toutes les communications sont chiffrées de manière à prouver que les requêtes sont transmises au serveur authentifié et que les réponses sont reçues de ce serveur.

HTTPS vous assure donc que vous vous adressez bien au serveur auquel vous pensez vous adresser, et que personne d'autre n'écoute ni ne modifie les bits sur le fil. Ce type de chiffrement est une condition préalable absolue pour la sécurité sur le Web. Si votre application n'est pas actuellement diffusée via HTTPS, elle est vulnérable aux attaques. Veuillez le corriger. Ars Technica propose un excellent guide pour obtenir et installer un certificat (sans frais) que je vous recommande de consulter pour en savoir plus sur les détails techniques. La configuration varie d'un fournisseur à l'autre et d'un serveur à l'autre, mais la procédure de demande de certificat est la même partout.

Sécurisation par défaut

Une fois que vous avez demandé et installé un certificat, assurez-vous que vos utilisateurs bénéficient de votre travail acharné: migrez vos utilisateurs existants vers des connexions HTTPS de manière transparente grâce à la magie de la redirection HTTP, et assurez-vous que les cookies ne sont que diffusés via des connexions sécurisées.

Par ici, s'il vous plaît

Lorsqu'un utilisateur accède à http://example.com/, redirigez-le vers https://example.com/ en envoyant une réponse 301 Moved Permanently avec un en-tête Location approprié:

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

Vous pouvez configurer facilement ce type de redirection sur des serveurs tels qu'Apache ou Nginx. Par exemple, une configuration Nginx qui redirige de http://example.com/ vers https://example.com/ se présente comme suit:

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

Les cookies nous permettent d'offrir aux utilisateurs une expérience de connexion fluide via le protocole HTTP sans état. Les données stockées dans les cookies, y compris les informations sensibles telles que les ID de session, sont envoyées avec chaque requête, ce qui permet au serveur de déterminer à quel utilisateur il répond actuellement. Une fois que nous nous sommes assurés que les utilisateurs accèdent à notre site via HTTPS, nous devons également nous assurer que les données sensibles stockées dans les cookies ne sont jamais transférées que via une connexion sécurisée et ne sont jamais envoyées en clair.

La configuration d'un cookie implique généralement un en-tête HTTP qui se présente comme suit:

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

Vous pouvez demander au navigateur de limiter l'utilisation du cookie pour sécuriser les sessions en ajoutant un seul mot clé:

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

Les cookies définis avec le mot clé secure ne seront jamais envoyés via HTTP.

Fermeture de la fenêtre ouverte

La redirection transparente vers HTTPS signifie que la grande majorité du temps où vos utilisateurs se trouvent sur votre site, ils utilisent une connexion sécurisée. Il laisse toutefois une petite fenêtre d'opportunité pour une attaque: la connexion HTTP initiale est grande ouverte et vulnérable au dénudage SSL et aux attaques associées. Étant donné qu'un pirate informatique a un accès complet à la requête HTTP initiale, il peut agir en tant que proxy entre vous et le serveur, vous maintenant sur une connexion HTTP non sécurisée, quelles que soient les intentions du serveur.

Vous pouvez atténuer le risque de cette classe d'attaque en demandant au navigateur d'appliquer le mécanisme HTTP Strict Transport Security (HSTS). L'envoi de l'en-tête HTTP Strict-Transport-Security indique au navigateur d'effectuer la redirection HTTP vers HTTPS côté client, sans jamais toucher au réseau (ce qui est également excellent pour les performances ; la meilleure requête est celle que vous n'avez pas à effectuer):

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Les navigateurs compatibles avec cet en-tête (actuellement Firefox, Chrome et Opera: caniuse fournit des informations) indiquent que ce site particulier a demandé un accès HTTPS uniquement, ce qui signifie que quel que soit le mode d'accès de l'utilisateur, il accédera au site via HTTPS. Même si elle saisit http://example.com/ dans le navigateur, elle accédera à HTTPS sans jamais établir de connexion HTTP. Mieux encore, si le navigateur détecte un certificat non valide (qui tente peut-être d'usurper l'identité de votre serveur), les utilisateurs ne sont pas autorisés à continuer via HTTP. C'est tout ou rien, ce qui est excellent.

Le navigateur expirera l'état HSTS du serveur au bout de max-age secondes (environ un mois dans cet exemple). Définissez cette valeur sur une valeur raisonnablement élevée.

Vous pouvez également vous assurer que tous les sous-domaines d'une origine sont protégés en ajoutant la directive includeSubDomains à l'en-tête:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Avancez en toute sécurité

Le protocole HTTPS est le seul moyen d'être même vaguement sûr que les données que vous envoyez parviennent intactes au destinataire prévu. Vous devez configurer dès aujourd'hui des connexions sécurisées pour vos sites et applications. Il s'agit d'un processus assez simple qui vous aidera à protéger les données de vos clients. Une fois que vous avez mis en place un canal chiffré, vous devez rediriger de manière transparente les utilisateurs vers cette connexion sécurisée, quel que soit le moyen par lequel ils accèdent à votre site, en envoyant une réponse HTTP 301. Assurez-vous ensuite que les informations de session sensibles de tous vos utilisateurs n'utilisent que cette connexion sécurisée en ajoutant le mot clé secure lorsque vous définissez des cookies. Une fois que vous avez fait tout cela, assurez-vous que vos utilisateurs ne tombent jamais accidentellement du bus: protégez-les en vous assurant que leur navigateur fait ce qu'il faut en envoyant un en-tête Strict-Transport-Security.

La configuration du protocole HTTPS ne demande pas beaucoup d'efforts et offre d'énormes avantages à votre site et à ses utilisateurs. L'effort en vaut la peine.

Ressources

  • StartSSL propose des certificats sans frais validés par domaine. Rien ne vaut un essai sans frais. Il est bien sûr possible d'obtenir des niveaux de validation plus élevés à un prix raisonnable.
  • Test du serveur SSL: une fois que vous avez configuré HTTPS pour vos serveurs, vérifiez que vous l'avez fait correctement en l'exécutant via le test du serveur de SSL Labs. Vous recevrez un rapport très détaillé qui vous indiquera si vous êtes vraiment opérationnel.
  • L'article récent d'Ars Technica Securing Your Web Server with SSL/TLS (Sécuriser votre serveur Web avec SSL/TLS) est intéressant à lire pour en savoir plus sur les principes de base de la configuration d'un serveur.
  • La spécification HTTP Strict Transport Security (RFC6797) est utile pour obtenir toutes les informations techniques possibles sur l'en-tête Strict-Transport-Security.
  • Une fois que vous savez vraiment ce que vous faites, vous pouvez indiquer que votre site ne doit être accessible que via un ensemble spécifique de certificats. Des travaux sont en cours à l'IETF pour vous permettre de le faire via l'en-tête Public-Key-Pins. Il est encore trop tôt pour en parler, mais c'est intéressant et cela vaut la peine de suivre ces travaux.