Site icon Sophos News

Authentification SSO : un bug au niveau du SAML (Security Assertion Markup Language)

SAML

Duo, la société spécialisée dans les accès et les connexions sécurisés, a récemment trouvé une faille plutôt inquiétante dans sa propre passerelle d’authentification.

Quelques recherches nous ont révélé que la faille de sécurité était présente dans beaucoup d’autres applications dites SSO (Single-Sign-On), en raison d’un problème dans la gestion de la “langue d’authentification” de base, qui est devenue un standard pour les produits dans ce domaine particulier.

Duo a divulgué le problème de manière responsable l’année dernière, et après avoir donné aux éditeurs, Duo y compris, le temps de corriger le bug, qui a été maintenant rendu public avec une explication excellente et pédagogique sur les événements qui ont eu lieu.

Dans le vocabulaire du SSO, l’authentification réseau utilise des serveurs d’authentification dédiés, connus sous le nom de IdPs (fournisseurs d’identité), afin de valider les demandes émanant des logiciels client (utilisateurs) pour accéder aux serveurs sur le réseau, appelés SPs (fournisseurs de services).

Ainsi vous n’avez pas besoin de programmer un module d’authentification, ni de gérer une base de données de mots de passe séparée, ni d’exécuter un autre service d’authentification à deux facteurs pour chaque serveur.

Dans le jargon, vous utilisez un serveur SSO IdP pour gérer les noms d’utilisateur et les mots de passe pour tous les autres fournisseurs de services sur le réseau.

Bien sûr, si vous voulez que différents clients et fournisseurs de services en provenance de différents éditeurs travaillent correctement ensemble avec un fournisseur d’identité d’un autre éditeur, vous avez besoin d’un langage de données et d’un vocabulaire uniformes pour qu’ils puissent communiquer.

Un tel langage est un SAML, l’abréviation de Security Assertion Markup Language.

Un SAML est un dialecte du XML, qui est une sorte de HTML édulcoré, le langage utilisé pour créer des pages web.

Maintenant, si vous avez écrit des logiciels ou des scripts qui génèrent des pages web au format HTML, vous saurez que c’est très simple à faire : il suffit simplement d’ajouter les bonnes balises à la fin de chaque phrase en gras, de chaque lien web, de chaque paragraphe, de chaque élément dans une liste à puces, et ainsi de suite.

Facile !

Mais si vous avez déjà eu à écrire un logiciel pour faire l’inverse, à savoir lire en HTML ou XML de manière intelligible, alors vous commencez à deviner le but de cet article !

Difficile !

NB : Générer du HTML et le relire de manière fiable est à peu près aussi difficile que d’utiliser quelques mots mal prononcés dans une langue étrangère, pour trouver votre chemin vers la gare, et pouvoir parler couramment avec une personne dont c’est la langue maternelle.

A quoi ressemble le bug ?

Duo nous a fait une faveur en produisant une représentation simplifiée des parties importantes dans une réponse d’authentification SAML : nous avons suivi leur exemple synthétique ci-dessous.

Une réponse SAML contient généralement une assertion au format XML qui identifie l’utilisateur authentifié, comme ceci :

<Assertion ID="ABC1245">
    <Subject><NameID>user@example.com</NameID></Subject>
</Assertion>

Il doit également y avoir une signature numérique pour cette assertion (ici identifiée par la séquence ABC1245), sans laquelle un imposteur pourrait simplement copier une réponse SAML, et modifier tout simplement le NameID pour faire référence à un compte différent :

<Signature>
   <SignedInfo><Reference URI="#ABC1245"/></SignedInfo>
   <SignatureValue>digital sig of assertion ABC1245</SignatureValue>
</Signature>

Le problème rencontré par Duo était de savoir comment diverses bibliothèques de programmation, y compris python-saml utilisées par Duo, ainsi que ruby-saml et saml2-js, traitaient des commentaires XML dans les structures de données SAML, et comment ces commentaires affectaient le processus de signature numérique.

Ci-dessus, la séquence de données correcte pour le champ NameID est évidemment user@example.com, représentant le texte complet directement entre la balise de début NameID et la balise de fin /NamedID.

Mais si vous deviez écrire ceci à la place …

<Assertion ID="ABC1245">
    <Subject><NameID>user@example.com<!-- comment -->.test</NameID></Subject>
</Assertion>

… quelle est la valeur correcte de NameID, étant donné que le texte <!-- comment --> est censé être ignoré ?

Duo a constaté que des bibliothèques SAML buggées pourraient lire la chaîne NameID de diverses manières, parfois en tant que user@example.com (en traitant le commentaire comme un terminateur de champ de données), et parfois en tant que user@example.com.test (en traitant simplement le commentaire comme s’il n’existait pas).

L’une ou l’autre interprétation est valide techniquement, et peu importe l’approche que vous choisissez, tant que vous restez cohérent.

Cependant, Duo a constaté que ce n’était pas le cas : les bibliothèques SAML buggées utiliseraient l’interprétation user@example.com lors de la validation de la signature, mais la deuxième interprétation lors de la verification du nom d’utilisateur.

En d’autres termes, en injectant un commentaire suivi d’un texte supplémentaire dans le champ NameID au sein d’une réponse SAML signée, un cybercriminel peut modifier le nom d’utilisateur dans le message d’authentification sans invalider sa signature numérique.

En conséquence, la réponse altérée s’avèrerait valide, incitant ainsi des serveurs sur le réseau à faire confiance à un utilisateur non autorisé.

Quoi faire ?


Billet inspiré de Single Sign-On authentication – the bug that lets you logon as someone else, sur Sophos nakedsecurity.

Exit mobile version