• Perspective
Publié le 12 mars 2014

Failles SSL/TLS, bonnes pratiques de développement et audits de code

Deux vulnérabilités sévères sont survenues coup sur coup impactant la vérification de certificats SSL/TLS dans la libsecurity_ssl d'Apple (web.nvd.nist.gov) et dans la libgnutls-x509 de GnuTLS (web.nvd.nist.gov). Le 21 février, Apple a publié un correctif de sécurité majeure pour iOS (7.0.6 et 6.1.6) (support.apple.com) dont la description un peu lapidaire a alimenté les rumeurs et critiques.

Un très bon article (imperialviolet.org) analyse la vulnérabilité en détails à partir de la fonction SSLVerifySignedServerKeyExchange incriminée faisant partie du code rendu open source par Apple (opensource.apple.com). Cette fonction vérifie la signature d'un ServerKeyExchange message utilisé dans les méthodes d'échange de clés TLS_ECDHE et TLS_DHE (en.wikipedia.org). Un "goto" inutile a été ajouté avec une identation indiquant qu'il devait être lié au "if" précédent. Cela a pour conséquence de faire tourner la fonction de façon inconditionnelle tout en indiquant le succès de la vérification... même quand la signature est fausse.

Un attaquant pourrait ainsi facilement réaliser une attaque de type "Man-in-the-Middle"MitM en montant un serveur web avec la ciphersuite qui l'arrange (TLS_ECDHE ou TLS_DHE) et envoyer une clé privée non valide avec le bon certificat dans le handshake. C'est pourquoi nous vous conseillons de mettre à jour rapidement vos appareils Apple pour combler cette faille.

Cette vulnérabilité est étonnante. Par son énormité et son exposition, on peut faire taire tout soupçon conspiratiste et privilégier une simple erreur de merge d'un développeur. Celle-ci aurait pu être évité si les bonnes pratiques de développement et de codage avait été respectées. Cependant, l'inconstance dans l'utilisation d'espaces et de tabulations, ainsi que de parenthèses autour des instructions solitaires après un "if" témoigne de cette absence de vérification. Douglas Crockford, le père du JavaScript, prêche depuis longtemps de bonnes pratiques parfois vues comme désuettes (github.com) mais qui auraient empêché cette erreur : "Braces should be used around all statements, even single statements, when they are part of a control structure, such as an if or for statement. This makes it easier to add statements without accidentally introducing bugs." (javascript.crockford.com). On note que des langages comme Python, Haskell ou Occam avec leur "significant whitespaces" ne sont pas sujet à ce type d'erreur.

Une deuxième vulnérabilité est étonnamment apparue dans le sillage de la première, suite à un audit mené pour RedHat (rhn.redhat.com) (peut-être il faut-il y voir un lien ?). Toutes les versions de la librairie GnuTLS sont affectées et permettent à un attaquant de forger un certificat particulier qui sera toujours reconnu valable. Une attaque de type "Man-in-the-Middle" pourrait donc également être réalisée. Cet article explique très bien les détails de cette erreur élémentaire de programmation : http://blog.existentialize.com/the-story-of-the-gnutls-bug.html. Il s'agit d'une confusion de convention entre les valeurs de retour traditionnelles du C (0 en cas de succès, -1 en cas d'erreur) et des valeurs de retour booléennes (0 pour une erreur, 1 pour un succès) qui a pu se produire suite à de multiples refactoring. Le choix d'une seule et unique convention aurait pu éviter cela.

La librairie GnuTLS étant heureusement peu utilisée en comparaison d'OpenSSL, les opportunités d'exploitation de cette vulnérabilité sont plus faible par rapport à la vulnérabilité iOS. En revanche, les impacts peuvent être plus importants : là où Apple peut déployer de façon centralisée ses nouveaux binaires sur tous ses appareils, il faudra du temps avant que tous les binaires corrigés soient déployés ou compilés sur les systèmes utilisant GnuTLS.

En synthèse, nous pouvons tirer deux conclusions de l'apparition de ces vulnérabilités :

  • Les codes sensibles, même Open Source, ne sont pas suffisamment relus, revus et testés
  • Les bonnes conventions de codage sont assez peu souvent employées et suivies

Nb : Il est intéressant de noter qu'un outil d'analyse statique, PVS-Studio, et qu'une option de clang absente de gcc, -Weverything détectent cette erreur. (reddit.com).

Pour plus de lecture sur le sujet, un résumé des "one line fixes" responsables des failles de sécurité (tedunangst.com) avec quelques réflexions intéressantes sur les conventions de codage (tedunangst.com). En complément, vous trouverez des informations sur la sécurité du triple handshake sur ce site : https://secure-resumption.com/

Article rédigé par
Erwan Brouder