Interrogation d'intermédiaires malveillants avec HTTPS et HTTP Strict Transport Security

Compte tenu de la quantité de données personnelles qui circulent à travers l'immense série de tubes qu'est Internet, le chiffrement n'est pas quelque chose que nous pouvons ou devons légèrement ignorer. Les navigateurs récents proposent plusieurs mécanismes permettant de garantir la sécurité des données de vos utilisateurs en transit: les cookies sécurisés et la norme Strict Transport Security sont deux des plus importants. Elles vous permettent de protéger facilement vos utilisateurs en mettant à niveau leurs connexions vers HTTPS et de vous garantir que les données utilisateur ne sont jamais envoyées en clair.

Quel est l'intérêt pour vous ? Réfléchissez aux points suivants:

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

La plupart des inconnus de cette chaîne improvisée sont dignes de confiance et ne regarderaient jamais votre lettre ouverte et ne la modifieraient jamais. Cependant, plus une lettre change de main, plus le nombre de personnes disposant d'un accès total à la lettre que vous envoyez est important. En fin de compte, il est fort probable que le destinataire de votre lettre reçoive quelque chose par la poste, mais est-ce que ce même élément que vous avez transmis en premier est une question ouverte. Peut-être que tu aurais eu dû sceller cette enveloppe...

Intermédiaire

Pour le meilleur ou pour le pire, d'immenses étendues d'Internet dépendent de la fiabilité des personnes que vous ne connaissez pas. Les serveurs ne sont pas directement connectés les uns aux autres, mais transmettent les requêtes et les réponses d'un routeur à un autre dans un jeu de téléphone colossal.

Vous pouvez observer ces sauts en action avec traceroute. Le chemin entre mon ordinateur et HTML5Rocks ressemble à ceci:

$ 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 mal, vraiment. Toutefois, si j'envoie des requêtes via HTTP, chacun de ces routeurs intermédiaires dispose d'un accès complet à mes requêtes et aux réponses des serveurs. Toutes les données sont transférées sous forme de texte brut non chiffré, et l'un de ces intermédiaires peut agir en tant qu'homme du milieu, lire mes données ou même les manipuler pendant leur transit.

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 il n'existe aucun mécanisme vous permettant de vous assurer que les données reçues correspondent exactement aux données envoyées. Si quelqu'un décide de rouler mon Internet pour rire, alors je n'ai plus ou moins de chance.

Cette ligne est-elle sécurisée ?

Passer du HTTP en texte brut à une connexion HTTPS sécurisée constitue votre meilleure défense contre les intermédiaires. Les connexions HTTPS chiffrent l'ensemble du canal de bout en bout avant l'envoi des données, ce qui empêche les machines 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é qu'offre HTTPS repose sur le concept de clés cryptographiques publiques et privées. Une discussion approfondie sur les détails dépasse (heureusement) le cadre de cet article, mais le principe de base est relativement simple: les données chiffrées avec une clé publique donnée ne peuvent être déchiffrées que 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 possède la clé privée appropriée. Toutes les communications à partir de ce moment-là sont chiffrées de manière à prouver que les requêtes sont transmises au serveur authentifié et que les réponses sont reçues.

Par conséquent, HTTPS vous donne l'assurance que vous vous adressez au serveur auquel vous pensez vous adresser, et que personne d'autre n'écoute ni n'interagit avec le réseau. Ce type de chiffrement est une condition préalable absolue à la sécurité sur le Web. Si votre application n'est actuellement pas 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). Je vous recommande de le consulter pour obtenir des détails techniques. La configuration sera différente d'un fournisseur à l'autre et de serveur à serveur, mais le processus de demande de certificat est le 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: migrez vos utilisateurs existants vers des connexions HTTPS de manière transparente grâce à la redirection HTTP, et assurez-vous que les cookies ne sont transmis que via des connexions sécurisées.

De cette façon, veuillez

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 facilement configurer ce type de redirection sur des serveurs comme Apache ou Nginx. Par exemple, une configuration Nginx qui effectue une redirection 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 d'identifier l'utilisateur auquel il répond à un moment donné. Une fois que nous avons vérifié 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 transférées que via une connexion sécurisée, et jamais envoyées en clair.

La définition d'un cookie implique généralement un en-tête HTTP qui ressemble à ceci:

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 cliquant sur 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.

Fermer la fenêtre ouverte

La redirection transparente vers HTTPS signifie que la grande majorité du temps que les utilisateurs passent sur votre site, ils utilisent une connexion sécurisée. Toutefois, elle laisse une petite fenêtre d'opportunité d'attaque: la connexion HTTP initiale est ouverte en grande partie, vulnérable à la suppression du protocole SSL et aux attaques associées. Étant donné qu'un "man in the middle" dispose d'un accès complet à la requête HTTP initiale, il peut agir en tant que proxy entre vous et le serveur, vous permettant ainsi de maintenir une connexion HTTP non sécurisée, quelles que soient les intentions du serveur.

Vous pouvez atténuer le risque d'une telle 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 le réseau (cela est également très avantageux 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 qui acceptent cet en-tête (actuellement Firefox, Chrome et Opera: caniuse has details) signaleront que ce site particulier a demandé un accès HTTPS uniquement, ce qui signifie que, quelle que soit la façon dont un utilisateur accède au site, il utilisera le protocole HTTPS. Même s'il saisit http://example.com/ dans le navigateur, il accède au protocole HTTPS sans établir de connexion HTTP. Mieux encore, si le navigateur détecte un certificat non valide (susceptible de falsifier l'identité de votre serveur), les utilisateurs ne seront 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 ce paramètre sur un niveau raisonnablement élevé.

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

Lancez-vous en toute sécurité

HTTPS est le seul moyen d'être sûr, même à distance, que les données que vous envoyez parviennent intactes au destinataire souhaité. Dès aujourd'hui, configurez des connexions sécurisées pour vos sites et vos applications. C'est un processus assez simple qui vous aidera à protéger les données de vos clients. Une fois votre canal chiffré en place, vous devez rediriger les utilisateurs de manière transparente vers cette connexion sécurisée, quelle que soit leur provenance, en envoyant une réponse HTTP 301. Assurez-vous ensuite que toutes les informations de session sensibles de vos utilisateurs n'utilisent que cette connexion sécurisée en ajoutant le mot clé secure lorsque vous définissez les cookies. Une fois cette opération effectuée, assurez-vous que vos utilisateurs ne tombent jamais accidentellement du bus: protégez-les en vous assurant que leur navigateur fonctionne correctement en envoyant un en-tête Strict-Transport-Security.

La configuration du protocole HTTPS ne représente pas beaucoup de travail, et présente d'énormes avantages pour votre site et ses utilisateurs. L’effort en vaut largement la peine.

Ressources

  • StartSSL propose des certificats sans frais avec validation du domaine. Vous ne pouvez pas battre votre temps libre. Passer à des niveaux de validation supérieurs est, bien sûr, possible et à un prix raisonnable.
  • Test de serveur SSL: une fois que vous avez configuré HTTPS pour vos serveurs, vérifiez que vous avez fait les bons choix en exécutant le test du serveur de SSL Labs. Vous obtenez alors un rapport très détaillé qui vous indique si vous êtes vraiment opérationnel.
  • Il est utile de lire l'article récent d'Ars Technica Sécuriser votre serveur Web avec SSL/TLS pour avoir un peu plus de détails sur les rouages de la configuration d'un serveur.
  • Il est intéressant de parcourir la spécification HTTP Strict Transport Security (RFC6797) pour trouver toutes les informations techniques dont vous pourriez avoir besoin sur l'en-tête Strict-Transport-Security.
  • Une fois que vous savez ce que vous faites, vous pouvez, par exemple, annoncer que votre site ne doit être accessible que via un ensemble spécifique de certificats. Des travaux en cours à l'IETF vous permettront de le faire via l'en-tête Public-Key-Pins. Il s'agit encore d'un travail qui n'en est qu'à ses débuts, mais qui est intéressant et mérite d'être suivi.