Ainsi donc, j'apprenais l'existence du projet jCryption qui nous propose une implémentation de RSA en JavaScript pour sécuriser les envois de formulaire sans utiliser SSL. De nombreux hébergeur ne fournissant pas le support SSL à leurs clients, le but peut sembler louable et l'idée intéressante. Seulement oui mais non : c'est bel et bien une idée à la con qui n'a heureusement pas fait réagir que moi...

Meik pointe très précisément une énorme faille technique de la solution quand il cite la FAQ :

jCryption offers no way of authentication

C'est à se demander si l'auteur de ce truc est allé à l'école ou s'il a même ne serait-ce que réfléchit au problème qu'il essaye de résoudre. Ses réponses aux commentaires qui pointent ce défaut tendraient plutôt à démontrer que non. Nous dissertions dans des billets précédants de l'importance de la maîtrise technique en sécurité informatique, mais quand celle-ci ne s'accompagne pas d'une compréhension fine des concepts, même abstraits, qu'on manipule, elle ne sert à rien.

Quand je commence la partie flux chiffrés de mon cours de sécurité réseau, je dois répéter trois ou quatre fois que la phase critique d'un protocole de chiffrement est l'authentification. Sans forcément entrer dans la technique, il est relativement simple de comprendre qu'on ne peut pas assurer la confidentialité d'une communication si on n'est pas capable de s'assurer de l'identité de son destinataire. L'attaque classique que permet de détecter une bonne authentification est typiquement le "Man in the Middle" dont la réussite suppose précisément l'usurpation de l'identité d'une partie vis-à-vis de l'autre et inversement.

Et donc, quand on lui pointe le problème, l'auteur nous démontre sa totale incompréhension du contexte :

When someone is between you and "the internet" you probably 
will have bigger problems than protecting your form data.
jCryption protects form data against sniffers, in an open 
wlan for example.

Ça se passe de commentaire. Vraiment. C'est juste pathétique.

Mais à bien y réfléchir, le problème de jCryption est bien plus profond que ce détail technique en ce qu'il tient dans son mode de fonctionnement global. C'est un JavaScript[1] ! Ceci veut dire que le code va être ramené par le client depuis une ressource non authentifiée, donc sans aucune garantie d'intégrité, et exécuté. Sans parler de code malicieux, le simple problème du phishing est complètement hors-scope ici, alors que c'est une des menaces principales qui pèsent sur la confidentialité des données soumises sur le web... De plus, comme vous pouvez faire du MiM, vous n'avez même pas besoin d'attaquer la crypto : il vous suffit de supprimer le code JS à la volée ! Voire de le modifier si vous êtes plus joueur.

On me rétorquera que si on vire jCryption de la page reçue par le client, ce dernier ne pourra plus soumettre ses données, puisque le serveur attend un contenu chiffré. Mais on s'est fout ! Ce qui intéresse l'attaquant, c'est juste que le client balance ses données sur le réseau. On avancera aussi qu'on pourrait signer le JavaScript en question pour assurer son intégrité. Encore une fois, ça n'empêchera pas un attaquant de le supprimer, de rajouter du code additionnel, de possiblement surcharger les méthodes du code signé ou carrément d'en supprimer les appels dans le code HTML. Ben oui, ce n'est pas parce qu'une page inclut du code JS qu'elle va forcément l'utiliser. Et je ne parle même pas de l'éventualité d'un XSS dans la page...

Bref, jCryption, c'est un pur échec conceptuel...


Un deuxième exemple d'idée brillantissime m'a été rappelé par le dernier billet de Jose Nazario qui décrit un canal de contrôle de botnet basé sur Twitter. Dans le cas présent, le maître du botnet poste ses ordres via des messages Twitter, les bots n'ont qu'à suivre le fil RSS. Mais le système peut également s'envisager dans l'autre sens, c'est à dire des bots qui viendraient alimenter un fil. Twitter est un exemple qui vient immédiatement à l'esprit, on peut également penser à un blog, via des billets ou des commentaires, mais aussi à des choses plus libres, genre Facebook.

Il y a quelques mois, on m'avait demandé mon avis sur un papier anonymisé intitulé "Protecting Web 2.0 Services from Botnet Exploitations" soumis à une conférence académique. J'avais résisté à l'envie de me lâcher parce qu'il n'avait pas été publié, mais comme il semble avoir été récemment présenté à une autre conférence, on peut le considérer comme public... Globalement, ce papier commence par décrire les botnets et le second cas évoqué au-dessus, c'est à dire l'exploitation croissante des services dits Web 2.0, en l'occurence les plate-formes de blogging, par des bots pour remonter des informations au botmaster. Et devant ce constat alarmant, de proposer une solution permettant à ces plate-formes de détecter et in fine bloquer de telles tentatives de détournement de service.

L'idée de base étant de différencier un utilisateur légitime d'un bot, le système s'appuie sur un système client-serveur utilisant des CAPTCHA. Classique. Mais comme l'auteur se rend bien compte que conditionner toutes les manipulations que peut faire un utilisateur à la résolution d'un CAPTCHA ne va pas lui plaire du tout, il a ajouté un système de tokens permettant au client de prouver au serveur qu'il a déjà résolu un CAPTCHA avec succès via un mécanisme challenge/réponse basé sur... l'adresse MAC de la machine et... géré par du code s'exécutant côté client...

Et là, quand je lis ça dès la deuxième page de description de la solution, je ne peux que m'arrêter pour essayer d'identifier la source de cette odeur d'échec qui commence à flotter dans l'air. Reprenons le concept. Ce système est fait pour différencier un utilisateur humain d'un bot. OK. Le bot s'exécute sur une machine compromise. OK. Le bot peut prendre le complet du navigateur par une tripottée de techniques qu'on trouve largement implémentée dans la nature, en particulier à des fins de phishing. OK. Essayons de comprendre la situation. Un bot veut poster une update et reçoit un CAPTCHA. S'il ne peut pas le résoudre, il doit faire intervenir un humain. Les gens qui aiment les systèmes compliqués se souviendront peut-être d'une technique de ce type encore largement utilisée pour résoudre massivement des CAPTCHA. Non, il ne s'agit pas d'employer de la main d'œuvre à bas prix, mais de combiner le système avec une plate-forme populaire, typiquement un site pornographique, dont les utilisateurs sont amenés à résoudre les CAPTCHA collectés par les bots. Et ça marche. Mais dans le cas présent, on a plus simple : il suffit de le faire faire par le botmaster.

Oui mais il ne va pas passer son temps à résoudre des CAPTCHA. Clairement, mais avec la solution étudiée, si nous trouvons un moyen d'abuser le système de tokens, nous pouvons autoriser tous les bots à poster sur la même plate-forme après la résolution du premier en utilisant toujours la même adresse MAC. Deux manière de le faire à mon avis. Soit on se débrouille pour fournir à la partie cliente la MAC qui nous intéresse quand elle génère sa réponse, ce qui n'est pas forcément très compliqué pour le bot, puisqu'il a compromis la machine, donc le navigateur. Soit on utilise carrément sa propre implémentation qui répondra systématiquement avec la même MAC. Hummm.... Me voilà donc en train de chercher ce que l'auteur propose pour gérer ce problème. Ce qui me conduit à la partie "Security Analysis" qui identifie bel et bien les deux problèmes soulevés et y répond de manière... épique...

Pour le problème de spoofing d'adresse MAC, il argumente que comme l'adresse est fournie au client par l'OS, il faut compromettre ce dernier pour la spoofer, qu'une telle compromission devrait être prévenue ou tout du moins détectée par d'autres systèmes de sécurité et donc que ce n'est pas dans le scope de l'outil :

Hence, it is out of scope of the [Tool] and we can assume 
that the OS is not compromised and can always return  the 
correct permanent MAC address.

HELLO MACFLY !!!! La machine compromise jusqu'à l'os, c'est précisément ton cas de figure !!!! Et même sans aller aussi loin, l'implémentation étant une applet Java apparemment poussée par le service Web, elle s'exécute dans le contexte du navigateur. Ses appels à l'OS peuvent donc être interceptés par le bot. Headshot, game over. Il faudrait donc considérer qu'il s'agit d'un outil installé sur le poste client et s'exécutant à un niveau de privilège plus élevé que celui de l'utilisateur. Je ne sais pas vous, mais moi, j'y crois moyen...

Pour ce qui est de l'intégration dans le bot d'une partie cliente malicieuse, la réponse est encore pire. La protection contre une telle implémentation consiste en effet en... tenez-vous bien... une clé secrète de 128 bits embarquée dans le binaire. Mais comme ils ont quand même vaguement entendu parler de gens qui feraient du reverse engineering, il vont se protéger contre ça :

we will compress and encrypt the [Tool] Client so that it is 
hard to be disassembled

Mega context fail... Autant dire que le papier n'a pas été accepté à la conférence en question[2]...


Dans la série "je ne comprends pas le problème que j'essaye de résoudre", voici donc deux beaux exemples. Le premier problème a ceci de particulier qu'il a déjà une solution qui s'appelle SSL. Alors oui, j'entends bien que c'est destiné aux gens dont l'hébergeur ne propose justement pas le support SSL. Ce à quoi je réponds qu'il faut savoir ce qu'on veut dans la vie : soit on veut de la sécurité et ça implique d'accepter certaines contraintes[3], soit on n'en fait pas. Toujours est-il que dans la mesure où jCryption est destiné à protéger les données soumises par le client, mais qu'un tel choix de déploiement est fait par le gestionnaire du serveur, ce ne sont clairement ces maigres considérations de sécurité qui s'opposeront à un franc succès dans son adoption. Quand bien même ce serait un outil de sécurité. Il suffit juste de lire les commentaires sur le blog de l'outil ou chez Korben pour s'en convaincre...

Pour le papier, ce qui me semble particulièrement atterrant, c'est surtout que ce soit un papier académique écrit dans le cadre d'une thèse, donc un travail encadré, et qu'il a été retenu par un comité de programme. Les esprits taquins y verront les raisons de l'échec. Je suis pour ma part clairement moins pessimiste sur la recherche universitaire, mais il faut avouer que ce papier a de quoi soulever quelques doutes. Mais ne soyons pas mesquins, exception ne fait pas règle. Ceci dit, je serais l'encadrant de la thèse en question que je me poserais tout de même quelques questions...

Plus globalement, ces exemples posent la dure question de l'assimilation de certains concepts de base de la sécurité par les internautes de manière général, et par ceux que prend l'envie d'apporter leur pierre à l'édifice en particulier. Vouloir faire de la confidentialité sans authentification préalable devrait faire au moins lever le sourcil. Vouloir accorder de la confiance à des données provenant d'une machine compromise devrait soulever quelques interrogations. Alors je vois d'ici les esprits charitables se dire que je suis bien dur avec des gens de bonne volonté. Probablement. Mais comme disait Figaro, "Sans la liberté de blâmer..."

Notes

[1] Je ne fais pas de fixette sur JS, on pourrait dire exactement la même de tout code distribué par le serveur et executé par le navigateur : applet Java, ActiveX, VB, etc.

[2] Celle pour laquelle je devais donner mon avis, pas l'autre hein...

[3] Comme se payer un hébergement qui fournit du SSL...