David Madore's WebLog: Le HTTPS, c'est de la merde en boîte

Index of all entries / Index de toutes les entréesXML (RSS 1.0) • Recent comments / Commentaires récents

Entry #1757 [older|newer] / Entrée #1757 [précédente|suivante]:

(mardi)

Le HTTPS, c'est de la merde en boîte

Le HTTPS, c'est la version « sécurisée » (c'est-à-dire, chiffrée et signée/authentifiée) du protocole HTTP utilisé de façon générale pour véhiculer le Web. Pour Madame Michu, le HTTPS se manifeste par un petit cadenas fermé affiché quelque part par le navigateur et probablement par la sensation confortable que les données qu'on échange sont protégées (donc que le méchant hacker russe ne peut pas lire votre numéro de carte de crédit en passant). L'idée est bonne. La crypto est raisonnable. Malheureusement, l'implémentation — la péri-crypto, pourrait-on dire, ou, en fait, la politique — est épouvantable, à tel point que ce truc est tout simplement à jeter à la poubelle. Le problème est simple : tout le HTTPS du Web est basé sur une chaîne de confiance, dont la source (les autorités racines) ne fait absolument pas son travail, voire, se comporte comme des escrocs méritent exactement zéro confiance, ce qui, inévitablement, ramène à zéro la confiance qu'on peut avoir en tout le reste de l'édifice construit sur ces fondations pourries.

Le principe, c'est que pour établir une connexion sécurisée (chiffrée), les deux partenaires (le client, donc le navigateur Web qui veut accéder au site sécurisé, et le serveur de ce site sécurisé) s'identifient l'un à l'autre (en pratique, en fait, c'est généralement seulement le serveur qui s'identifie auprès du client) en échangeant des certificats qui permettent que chacun soit sûr de parler à la bonne personne et d'en connaître la bonne clé publique de chiffrement, pour pouvoir ensuite se mettre d'accord sur une clé. Le serveur, pour s'authentifier auprès du client, va fournir une chaîne de signatures : sa clé publique, avec son nom officiel et le nom du site qu'il opère, sont signés par une autorité avec une clé elle-même signée par une autre, et ainsi de suite jusqu'à une autorité racine que le navigateur connaît nativement. Dans la pratique, ces autorités intermédiaires sont du bidon, on peut faire comme si l'identité du site était signée directement par l'autorité racine. Tout ceci prend place dans le cadre défini par une moussaka géante appelée X.509.

Si les autorités racines faisaient un boulot un tant soit peu sérieux, et si Madame Michu comprenait ce qui se passe, ce système ne serait peut-être pas si mauvais. Le but est de se prémunir contre deux sortes de risques : le premier est l'attaque par un espion passif (eavesdropper) qui ne peut qu'espionner les communications sans les altérer : il s'agit du risque le plus vraisemblable, et pour ça on connaît en fait une méthode bien plus simple permettant d'assurer une communication privée résistante aux espion passifs sans même à avoir à authentifier les participants, c'est le protocole d'échange de clés de Diffie-Hellman ; l'autre risque, moins vraisemblable sur Internet mais aussi plus difficile à éviter et où il faut vraiment établir l'identité des participants, c'est l'attaque de l'homme au milieu (man-in-the-middle), c'est-à-dire un espion qui peut intercepter complètement la communication entre A et B et se faire passer pour A auprès de B et pour B auprès de A en recopiant les données mais en changeant les clés. J'estime que les attaques man-in-the-middle sont assez peu probables sur Internet, mais si on veut s'en protéger, il faut effectivement utiliser un système qui permet d'identifier l'interlocuteur et pas seulement de sécuriser un canal avec lui. Donc le principe général de HTTPS et de ses chaînes de signatures n'est pas absurde.

Les problèmes sont multiples. Un problème zéro est que Madame Michu n'a rien à faire de comprendre ces histoires de chiffrement et de signature, elle veut savoir si elle peut avoir confiance dans le site Web et dans la connexion : l'architecture garantit peut-être que la connexion soit sécurisée, éventuellement que le site Web soit bien qui il indique qu'il est, mais certainement pas qu'il est honnête ni même qu'il n'est pas quelqu'un d'autre avec un nom très subtilement semblable et avec lequel Madame Michu va probablement confondre. Dans cette optique, le problème principal est que les autorités racines ne font pas du tout ce qu'on attend d'elles. On attend d'elles (si on veut que le système fonctionne un peu) qu'elles vérifient soigneusement l'identité des personnes à qui elles délivrent des certificats, qu'elles vérifient que le nom ne prête pas à confusion, qu'il s'agit d'une compagnie vraiment implantée et pas d'un petit malin qui a fondée une association Société Généralle sans aucun rapport avec la Société Générale, etc. Ce que font en réalité les autorités racines, c'est recevoir de l'argent (parfois beaucoup) et mettre leur tampon sur les certificats sans regarder quoi que ce soit. Dès lors, le système est une pure escroquerie. Même si toutes les autorités racines ne sont pas des escrocs, il suffit qu'une seule le soit pour que tout le système soit pourri — or il y en a toute une ribambelle et on ne sait pas très bien, d'ailleurs, par quel processus elles sont choisies (cela dépend du navigateur : Firefox est un peu transparent sur la question, mais les autres navigateurs carrément moins, et certains aussi se contenent de recevoir de l'argent (toujours beaucoup) et mettre le certificat demandé parmiles certificats racines).

À ce compte-là — tant qu'à avoir un système qui ne vérifie rien, finalement, que le nom de domaine — on aurait pu faire plus simple et moins cher : avoir un système de signature qui suive le mécanisme hiérarchique du DNS : en achetant le domaine madore.org je recevrais automatiquement un certificat prouvant que je suis bien propriétaire du domaine en question, et signé par la clé du domaine org. C'est effectivement ce qui va se faire avec le DNS sécurisé, mais pour autant que je comprenne il n'est malheureusement pas prévu que ce système hiérarchique soit directement utilisable dans les navigateurs Web (probablement pour ne pas tuer la poule aux œufs d'or des escrocs qui détiennent des certificats racines).

Idéalement, le système que je voudrais avoir, moi (mais que je conviendrait probablement pas trop à Madame Michu), quand je me connecterais à un site sécurisé, il me dirait : bonjour, ceci est la première fois que vous vous connectez à un site du domaine exemple.tld : le certificat qui l'authentifie a été signé par <telle autorité> et <telle autorité> et <telle autorité> : voulez-vous continuer à vous connecter ? avec des options diverses permettant, par exemple, de marquer qu'on veut continuer la connexion mais sans faire confiance à la sécurité de la connexion (rappeler si besoin est que le canal n'est pas forcément sûr), ou je ne sais quoi du genre. (À tout le moins, même en l'absence de signature identifiant l'interlocuteur, on aurait une protection contre les espions passifs en utilisant un échange de type Diffie-Hellman, ce qui n'est déjà pas mal.) Quand le certificat expirerait (arriverait au bout de sa date de validité), j'aurais un message semblable me signalant de plus que le nouveau certificat utilise la même clé que précédemment ou est signé avec celle-ci (ce qui augmente ma confiance). Et surtout, si jamais le certificat change sans raison, même si le nouveau est signé par des autorités censément de confiance, j'aurais droit à un message expliquant la situation. C'est, grosso modo, les signatures en moins, comment fonctionne SSH.

Mais le HTTPS, en tout cas tel qu'il est implémenté dans les navigateurs, ne fonctionne pas du tout comme ceci. D'abord, ce système irrémédiablement mal foutu ne permet à un certificat d'être signé que par une autorité : on établit une chaîne de confiance et pas un réseau de confiance : pas moyen, donc, pour un site Web de faire signer son certificat par plusieurs autorités (ou par sa précédente clé en cas de changement) pour combiner un peu la confiance très limitée que j'apporte en chacune. Ensuite, on ne peut faire confiance que totalement ou pas du tout : si je donne ma confiance à une autorité, je ne serai pas prévenu d'un changement apporté au certificat d'un site que je consulte ; pas moyen, non plus, d'avoir un message particulier à la première connexion sauf à refuser complètement la confiance en l'autorité racine. Tout ceci est totalement nul.

Sur un de mes ordinateurs, j'ai fait l'expérience de retirer la confiance accordée par mon Firefox à tous les certificats des autorités racines. D'abord, ce n'est pas du tout facile à faire, même s'il y a peut-être eu des progrès depuis dans Firefox (dans EditPreferencesAdvancedEncryptionCertificatsView CertificatesAuthorities on peut régler des choses) ; j'ai gribouillé les notes suivantes, qui donnent une idée de combien c'est mal foutu :

### TO LIST DEFAULT ROOT CERTIFICATES:
cd "`mktemp -d`"
# Create a new certificate database:
certutil -N -d .
# (type return twice for empty password)
# Add roots from libnssckbi:
modutil -add roots -libfile /usr/lib/nss/libnssckbi.so -dbdir .
# replace /usr/lib/nss/libnssckbi.so by wherever libnssckbi is found on your system
# (confirm: this is a temporary directory so there is no danger)
# Check that the Builtin Object Token was added:
modutil -list -dbdir .
# Now you can list the contents of the Builtin Object Token:
certutil -L -d . -h "Builtin Object Token"

### TO UNTRUST ROOT CERTIFICATES:
# (Make sure Firefox is not running!)
cd .mozilla/firefox/$salt
# (replace $salt by wherever your profile is stored)
modutil -add roots -libfile /usr/lib/nss/libnssckbi.so -dbdir .
# (same comment as above for libnssckbi.so,
# but this time really make sure the browser is not running!).
TEMPFILE="`mktemp`"
certutil -L -d . -h "Builtin Object Token" | perl -ne 'next unless /^(.*?)\s+([A-Za-z]*\,[A-Za-z]*\,[A-Za-z]*)\s*$/; $n=$1; $v=$2; $v=~s/C/c/g; $v=~s/G//g; $v=~s/T/c/g; print "certutil -M -d . -n \"$n\" -t \"$v\"\n";' > "$TEMPFILE"
# Review or edit $TEMPFILE and possibly run it with:
. "$TEMPFILE"

Ensuite, évidemment, se connecter la première fois à n'importe quel site HTTPS conduit à un avertissement : ça c'est l'effet désiré, et je ne m'en plains pas. Je me plains, en revanche, du fait que cet avertissement est peu utile, et notamment il n'est pas du tout évident d'arriver à voir si la signature par l'autorité racine est valable ou non (je ne veux pas faire confiance automatiquement à une autorité racine, mais je veux quand même savoir si elle a ou non signé le certificat). Mais surtout, il y a pire : autant les choses se passent raisonnablement bien quand on essaie explicitement de se connecter à un site HTTPS (en entrant une URL en https:// ou en suivant un lien), autant quand c'est un script ou une image ou quelque chose comme ça que le navigateur essaie de charger depuis un domaine dont on n'a jamais accepté le certificat, la connexion échoue purement et simplement (ou alors avec une fenêtre d'avertissement qui ne propose qu'une seule option : faire échouer l'opération). Voilà qui est profondément crétin ! Même si le navigateur ne fait qu'aller chercher une erreur ou un bout de JavaScript à une adresse en https://, je veux voir la même page me proposant de voir le certificat et de choisir si je veux l'accepter ou non ! (Je me suis rendu compte du problème en essayant d'accéder à un site qui utilisait un CAPTCHA en https://, probablement ReCAPTCHA, et qui n'apparaissait tout simplement pas. Du coup, je ne pouvais rien faire et j'ai mis un temps fou à comprendre ce qui se passait.) Il y a aussi des problèmes bizarres avec les extensions Firefox, qui n'ont pas l'air de se mettre à jour correctement (sans pour autant signaler à l'utilisateur qu'il est face à tel certificat signé de telle et telle manière) si on détruit la confiance dans les certificats racines. Bref, cela conduit à plein de problèmes, donc on est quasiment obligé d'accepter ces autorités racines…

…Sans pour autant que ça aide Madame Michu, qui risque tout à fait de tomber sur le domaine amazoon.com présentant un certificat en bonne et due forme signé par n'importe quelle autorité racine (donc montrant à Madame Michu le petit cadenas fermé qui lui inspire confiance) et qui ressemble comme deux gouttes d'eau à amazon.com mais qui appartient à une compagnie moins scrupuleuse. Madame Michu ne peut rien dire : le certificat montrait bien qu'elle était chez la compagnie Amazoon avec deux ‘o’, et l'autorité racine ne s'est jamais engagée à vérifier qu'il n'y avait pas ce genre de confusion. Tout ce système est à foutre à la poubelle.

Mise à jour : une entrée plus tardive sur ce même sujet (ou proche).

↑Entry #1757 [older|newer] / ↑Entrée #1757 [précédente|suivante]

Recent entries / Entrées récentesIndex of all entries / Index de toutes les entrées