Jetons d'accès liés au certificat client : ce que mTLS ajoute à OAuth
- Accueil
- Identités, accès & habilitations
- Gérer les accès externes des prestataires
- Jetons d'accès liés au certificat client : ce que mTLS ajoute à OAuth
Jetons d’accès liés au certificat client : ce que mTLS ajoute à OAuth
Section intitulée « Jetons d’accès liés au certificat client : ce que mTLS ajoute à OAuth »Un jeton d’accès au porteur fonctionne pour quiconque le présente. La façon la plus solide de corriger ce défaut consiste à exiger du client une authentification TLS mutuelle, puis à inscrire dans le jeton l’empreinte du certificat utilisé : la ressource vérifie que la connexion qui lui présente le jeton est établie avec ce même certificat, et refuse sinon. La RFC 8705, publiée en février 2020, normalise ce mécanisme et, accessoirement, deux manières d’authentifier un client OAuth par certificat. Les deux sujets sont dans le même document et se déploient indépendamment, ce qui est une source de confusion constante.
Un laissez-passer sur lequel est agrafée la photocopie d’une carte professionnelle ne s’utilise qu’en présentant la carte originale. Le gardien n’a pas besoin de savoir si la carte est authentique : il compare la photocopie agrafée à la carte qu’on lui montre. Qui ramasse le laissez-passer dans la rue n’a pas la carte, et le gardien n’a rien d’autre à faire que regarder.
→ Lire l’explication complète de la marmotte
Deux mécanismes dans un seul document
Section intitulée « Deux mécanismes dans un seul document »La RFC fait deux choses distinctes, et son abrégé les énonce séparément : elle fournit aux clients OAuth « un mécanisme d’authentification auprès du serveur d’autorisation utilisant TLS mutuel, fondé soit sur des certificats auto-signés soit sur une infrastructure à clés publiques », et elle fournit aux serveurs d’autorisation « un mécanisme pour lier les jetons d’accès au certificat TLS mutuel d’un client », les ressources protégées disposant alors « d’une méthode pour s’assurer qu’un jeton d’accès qui leur est présenté a bien été délivré au client qui le présente ».
La section 4 énonce la règle qu’il faut retenir : « l’authentification du client OAuth par TLS mutuel et les jetons d’accès liés au certificat peuvent être utilisés indépendamment l’un de l’autre ». On peut donc lier un jeton à un certificat sans authentifier le client par ce certificat, et c’est précisément le cas des clients publics, ceux qui n’ont pas d’accréditation associée à leur identifiant. Chaque instance d’un tel client crée un certificat auto-signé, le serveur d’autorisation ne s’en sert pas pour authentifier le client au niveau OAuth, mais il lie le jeton délivré au certificat dont le client a prouvé détenir la clé privée. Le jeton « ne peut alors être utilisé que par le client possédant le certificat et la clé privée correspondante ». La RFC ajoute que le jeton de rafraîchissement délivré à un tel client « DEVRAIT également être lié au certificat correspondant ».
Cette séparation est d’ailleurs ce qui fait la qualité du mécanisme : « lier le jeton d’accès au certificat client de cette façon a l’avantage de découpler cette liaison de l’authentification du client auprès du serveur d’autorisation, ce qui permet à TLS mutuel, lors de l’accès à la ressource protégée, de servir purement de mécanisme de preuve de possession ». La ressource n’authentifie personne ; elle compare.
Les deux méthodes d’authentification du client
Section intitulée « Les deux méthodes d’authentification du client »La méthode fondée sur une infrastructure à clés publiques, dont le nom de méthode est tls_client_auth, suit l’usage traditionnel des certificats X.509 : elle « repose sur une chaîne de certificats validée et sur un unique nom distinctif de sujet ou un unique nom alternatif de sujet pour authentifier le client ». Un seul nom par client, et la RFC prend soin de signaler le piège : « un traitement prédictible des valeurs de nom distinctif, comme la règle de correspondance de noms distinctifs de la RFC 4517, est nécessaire » pour comparer le sujet du certificat à celui enregistré. La vérification de révocation est possible, mais « si et comment vérifier l’état de révocation d’un certificat est une décision de déploiement à la discrétion du serveur d’autorisation », sujet traité dans la comparaison CRL et OCSP. Avantage pratique de cette méthode : les clients « peuvent faire tourner leurs certificats X.509 sans avoir besoin de modifier les données d’authentification correspondantes au serveur d’autorisation », en obtenant un nouveau certificat avec le même sujet auprès d’une autorité de confiance.
La méthode fondée sur un certificat auto-signé, dont le nom de méthode est self_signed_tls_client_auth, enregistre d’avance les certificats du client, ou une adresse vers une source de confiance qui les publie. Pendant l’authentification, « TLS est utilisé pour valider la possession par le client de la clé privée correspondant à la clé publique présentée dans le certificat », mais, et c’est la différence, « contrairement à la méthode PKI, la chaîne de certificats du client n’est pas validée par le serveur ». Le client est authentifié si le certificat présenté correspond à l’un de ceux enregistrés. Cette méthode « permet l’usage de TLS mutuel pour authentifier des clients sans avoir à maintenir une infrastructure à clés publiques », et, combinée à une adresse de publication plutôt qu’à une liste statique, elle autorise aussi la rotation sans intervention. C’est l’option raisonnable pour une intégration entre deux organisations qui n’ont pas de confiance commune à construire, cas traité par ailleurs dans authentifier une API B2B hors annuaire interne.
Une exigence commune aux deux méthodes mérite d’être notée parce qu’elle surprend : le client « DOIT inclure le paramètre client_id » dans toutes ses requêtes. La raison est d’ingénierie : « la présence du paramètre client_id permet au serveur d’autorisation d’identifier facilement le client indépendamment du contenu du certificat », de localiser sa configuration, et de vérifier le certificat présenté contre ce qui est attendu pour ce client précis. On ne déduit pas l’identité du certificat ; on la déclare, puis on vérifie que le certificat colle. L’inverse serait une recherche dans un annuaire pilotée par l’attaquant.
La liaison du jeton : une empreinte, et une comparaison
Section intitulée « La liaison du jeton : une empreinte, et une comparaison »Quand le client utilise TLS mutuel sur sa connexion au point de jeton, le serveur d’autorisation peut lier le jeton délivré au certificat, en associant celui-ci au jeton « d’une manière accessible à la ressource protégée ». Pour un jeton structuré en JWT, la RFC définit un membre de méthode de confirmation, x5t#S256, dont la valeur est « un condensé SHA-256 encodé en base64url de l’encodage DER du certificat X.509 », placé dans la revendication cnf. Pour un jeton opaque, la même information est obtenue par le point d’introspection.
La vérification côté ressource est décrite en deux obligations, et elles sont impératives : la ressource protégée « DOIT obtenir, de sa couche d’implémentation TLS, le certificat client utilisé pour TLS mutuel, et DOIT vérifier que le certificat correspond au certificat associé au jeton d’accès. S’ils ne correspondent pas, la tentative d’accès DOIT être rejetée » avec un code HTTP 401 et l’erreur invalid_token. Et le client, de son côté, doit faire ses requêtes « sur une connexion TLS mutuellement authentifiée utilisant le même certificat que celui utilisé pour TLS mutuel au point de jeton ».
Le point qui soulage l’exploitation est explicite dans les considérations d’implémentation : « il n’est pas nécessaire que le serveur de ressources valide la chaîne de confiance du certificat du client », et il « configurerait donc sa pile TLS de manière à ne pas vérifier si le certificat présenté par le client pendant la poignée de main est signé par une autorité de certification de confiance ». La ressource ne fait pas de PKI, elle fait une comparaison d’empreinte. Le choix de SHA-256 est justifié comme ailleurs par une résistance à la seconde préimage suffisante « pour rendre informatiquement infaisable de trouver ou créer un autre certificat produisant la même valeur de condensé », propriété détaillée dans les propriétés des condensés cryptographiques.
Ce que l’exploitation impose, et qui n’est pas négociable
Section intitulée « Ce que l’exploitation impose, et qui n’est pas négociable »Quatre contraintes font la différence entre un déploiement qui marche et un déploiement qui s’effondre en recette.
La ressource doit savoir à l’avance qu’elle veut un certificat. La RFC l’explique par la mécanique de TLS, et l’argument est définitif : « le jeton d’accès lui-même ne peut pas servir d’entrée à la décision de demander ou non TLS mutuel, parce que, du point de vue de TLS, il est de la donnée applicative, échangée seulement après que la poignée de main a été complétée, alors que la demande initiale de certificat survient pendant la poignée de main ». Conséquence : « il est attendu qu’il soit courant qu’un serveur de ressources utilisant TLS mutuel l’exige pour toutes les ressources qu’il héberge, ou serve les ressources protégées par TLS mutuel et les ressources ordinaires sur des combinaisons distinctes de nom d’hôte et de port ». Et la synchronisation de la politique entre ressource et serveur d’autorisation est « hors du périmètre » du document, formulation polie pour dire que c’est votre problème.
Demander un certificat a des effets de bord sur les autres clients. Le fait même qu’un serveur demande un certificat « peut entraîner un comportement indésirable de certains clients. C’est particulièrement vrai des navigateurs web comme clients TLS, qui présentent typiquement à l’utilisateur final une interface intrusive de sélection de certificat. » D’où l’introduction d’un paramètre de métadonnées, mtls_endpoint_aliases, qui publie des points d’accès alternatifs que les clients voulant faire du TLS mutuel utilisent de préférence aux points conventionnels. La RFC recommande aussi d’héberger le point de jeton sur un nom d’hôte ou un port séparé, « afin d’éviter un impact non souhaité sur le comportement TLS de ses autres points d’accès, par exemple le point d’autorisation ».
Renouveler un certificat invalide les jetons. Puisque le jeton est lié à un certificat précis, « les jetons d’accès sont invalidés quand un client met à jour son certificat », ce que la RFC propose de traiter « de la même manière que des jetons d’accès expirés », par une nouvelle demande suivie d’un nouvel essai. C’est faisable, à condition que le client sache le faire : un client qui traite un 401 comme une erreur fatale tombera à chaque renouvellement, et les renouvellements sont désormais fréquents. La mécanique d’enrôlement et de renouvellement automatisés est l’objet de EST pour enrôler des certificats X.509.
La terminaison TLS est un trou documentaire. La RFC l’admet en une phrase : un serveur « PEUT choisir de terminer les connexions TLS sur un répartiteur de charge, un proxy inverse ou un autre intermédiaire réseau. La manière dont les métadonnées du certificat client sont communiquées de manière sécurisée entre l’intermédiaire et le serveur applicatif est, dans ce cas, hors du périmètre. » C’est là que se logent les défauts réels : un en-tête ajouté par le répartiteur et non purgé des requêtes entrantes transforme toute la construction en déclaration volontaire. Le problème est le même que celui de la confiance dans les en-têtes ajoutés par un intermédiaire, exposé dans l’injection d’en-tête Host, et la vérification de ce qui est réellement authentifié en pratique est le sujet de l’audit de la couverture réelle du mTLS d’un maillage de services.
Un dernier point de périmètre, qui évite une mauvaise idée : la liaison des jetons délivrés directement par le point d’autorisation, dans le flux implicite, est « explicitement hors du périmètre », parce que « l’usage de certificats clients dans les navigateurs des utilisateurs apporte des problèmes opérationnels et d’ergonomie qui rendent indésirable » ce soutien. Les implémentations doivent donc utiliser des types d’octroi où le client demande son jeton directement au point de jeton.
Les risques résiduels, tels que la RFC les nomme
Section intitulée « Les risques résiduels, tels que la RFC les nomme »Usurpation de certificat. Avec la méthode fondée sur une infrastructure à clés publiques, « un attaquant pourrait tenter d’usurper l’identité d’un client en utilisant un certificat portant le même sujet mais délivré par une autorité de certification différente que le serveur d’autorisation accepte ». La parade est une réduction d’ancre de confiance : le serveur « DEVRAIT n’accepter comme ancres de confiance qu’un nombre limité d’autorités dont la politique d’émission satisfait ses exigences de sécurité ». La RFC ajoute l’hypothèse qu’il faut rendre explicite : « il y a une hypothèse que le client et le serveur s’accordent hors bande sur l’ensemble des ancres de confiance », faute de quoi « l’usage d’un sujet pour identifier le certificat client ouvrirait le serveur à des attaques d’usurpation de certificat ». C’est exactement le « ou » logique du magasin de confiance public, et la raison pour laquelle un magasin réduit vaut mieux ici qu’un magasin complet ; le modèle de confiance d’ensemble est exposé dans relier une clé à une identité.
Complexité de l’analyse X.509. La RFC consacre une section à une mise en garde qui mérite d’être affichée au-dessus de tout clavier : « l’analyse et la validation des certificats X.509 et des chaînes de certificats sont complexes, et des erreurs d’implémentation ont déjà exposé des vulnérabilités de sécurité ». Elle liste les difficultés : contraintes de base, usages de clé simples et étendus, périodes de validité, extensions critiques, octets nuls intégrés dans les chaînes de longueur comptée de l’ASN.1, représentations non canoniques des noms de sujet, motifs à joker, et vérification récursive des chaînes avec contrôle de révocation. Sa conclusion est une interdiction déguisée : les implémenteurs « DEVRAIENT utiliser une bibliothèque X.509 établie et bien testée, et NE DEVRAIENT PAS tenter d’écrire leurs propres procédures de validation de certificats X.509 ». Le détail des extensions dont il est question est dans les extensions X.509.
Vie privée. Dans les versions de TLS antérieures à 1.3, « le certificat du client est envoyé en clair dans la poignée de main initiale et peut potentiellement être utilisé par des tiers pour surveiller, suivre et corréler l’activité du client ». La RFC nuance avec justesse : peu importe pour un client qui agit pour un grand nombre d’utilisateurs, dont l’activité individuelle se noie dans la masse ; mais « les clients qui agissent pour le compte d’un seul utilisateur final, comme une application native sur un appareil mobile, devraient utiliser TLS 1.3 chaque fois que c’est possible ». La différence vient du chiffrement du certificat client dans la nouvelle poignée de main, décrite dans la poignée de main TLS 1.3 en une page.
Reste à conclure par la comparaison qui intéresse l’architecte. Cette liaison au certificat est techniquement plus forte que l’alternative applicative, parce qu’elle s’appuie sur l’intégration de la couche TLS, et la RFC qui définit cette alternative l’écrit elle-même : voir DPoP. Elle est aussi plus lourde, et impraticable pour un navigateur. Le partage est donc net : TLS mutuel entre services et entre organisations, preuve applicative pour ce qui tourne dans un navigateur ou sur un téléphone. Les profils de sécurité exigeants acceptent les deux et refusent le jeton au porteur nu, comme l’expose FAPI 2.0.
- RFC 8705 : OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens, B. Campbell, J. Bradley, N. Sakimura, T. Lodderstedt, IETF, février 2020.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Sans liaison du jeton à un certificat, un jeton d’accès intercepté s’utilise depuis n’importe quelle machine, et la ressource n’a aucun moyen de constater que son porteur n’est pas celui à qui il a été délivré. Sans paramètre d’identifiant de client dans la requête, le serveur d’autorisation doit déduire l’identité du contenu du certificat, ce qui transforme une vérification en recherche pilotée par l’appelant. Sans réduction des ancres de confiance, un certificat portant le même nom de sujet mais émis par une autre autorité acceptée suffit à usurper un client. Sans canal sûr entre le terminateur TLS et le serveur applicatif, l’empreinte du certificat devient un en-tête que l’appelant peut déclarer lui-même, et toute la construction se résume à une affirmation. Sans gestion du renouvellement côté client, chaque rotation de certificat invalide les jetons en cours et produit une panne. Et sans bibliothèque X.509 éprouvée, la validation des chaînes devient la vulnérabilité qu’elle était censée écarter.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Pour accéder à des données chez un service, un programme présente un jeton d’accès. Le problème est que ce jeton vaut pour quiconque le détient : s’il fuite, il s’utilise ailleurs. Une solution consiste à exiger que le programme s’identifie aussi au niveau de la connexion sécurisée, en présentant un certificat électronique, comme une carte professionnelle.
L’astuce est ensuite simple. Au moment de délivrer le jeton, le service calcule une empreinte du certificat présenté et l’inscrit dans le jeton. Plus tard, quand le programme appelle une ressource, celle-ci regarde quel certificat a servi à établir la connexion, calcule son empreinte, et la compare à celle inscrite dans le jeton. Si les deux ne correspondent pas, elle refuse. Un jeton volé devient donc inutilisable, parce que le voleur n’a pas la clé privée du certificat.
Détail qui facilite beaucoup la vie : la ressource n’a pas besoin de vérifier que le certificat est authentique, ni de connaître l’autorité qui l’a émis. Elle compare deux empreintes, et c’est tout. Le certificat ne sert pas à prouver une identité, mais à prouver qu’on est bien celui à qui le jeton a été remis.
En revanche, quatre contraintes d’exploitation sont incontournables. La ressource doit décider de demander un certificat avant de savoir quel jeton on lui présentera, car la négociation de la connexion a lieu d’abord ; en pratique, on dédie un nom de serveur ou un port à ces échanges. Demander un certificat perturbe les navigateurs, qui affichent une fenêtre de sélection désagréable, donc ces échanges doivent être isolés. Renouveler un certificat invalide les jetons en cours, et le programme doit savoir en redemander. Et si la connexion sécurisée est terminée par un répartiteur de charge, il faut que l’information du certificat parvienne au serveur applicatif de façon fiable, sinon elle devient une simple déclaration que n’importe qui peut écrire.
Cette méthode est la plus solide des deux qui existent pour attacher un jeton à son détenteur. Elle convient entre serveurs et entre organisations. Pour une application dans un navigateur ou sur un téléphone, on utilise l’autre, qui fait la preuve au niveau applicatif plutôt qu’au niveau de la connexion.
À lire aussi
- Échange de jetons OAuth : distinguer la délégation de l'usurpationComment un service échange le jeton de l'utilisateur contre un jeton pour appeler un troisième service, et la différence que fait la revendication act : agir pour le compte de quelqu'un, ou se faire passer pour lui.
- Requête d'autorisation poussée et signée (PAR, JAR)Deux mécanismes qui retirent au navigateur la garde des paramètres d'autorisation OAuth : l'envoi direct au serveur avant la redirection, et l'emballage de la requête dans un jeton signé.
- Gérer les accès externes des prestatairesConcevoir des accès externes, portails partenaires et fédérations inter-entreprises sans perdre la visibilité sur les identités tierces et la responsabilité des autorisations.
- Flux par code d'appareil : l'autorisation sur la télévision, et son hameçonnageLe flux OAuth des équipements sans clavier, son code court, son interrogation périodique et son expiration, et pourquoi la RFC 8628 consacre une section entière à l'hameçonnage à distance qu'il rend possible.
Pages voisines
La citent
- Assertion fédérée injectée : pourquoi une assertion valide ne suffit pas
- Niveaux d'assurance d'authentification : ce qu'il faut pour monter d'un cran
- Requête d'autorisation poussée et signée (PAR, JAR)
- CICD-SEC-6 : hygiène des identifiants insuffisante
Jetons d'accès liés au certificat client : ce que mTLS ajoute à OAuth
Elle cite
- Lien dans les deux sens :DPoP : attacher un jeton d'accès à une clé que le porteur doit prouver détenir
- Lien dans les deux sens :FAPI 2.0 : ce qu'un profil de sécurité interdit, et pourquoi
- Authentifier une API B2B hors annuaire interne
- EST : enrôler des certificats X.509 par transport sécurisé
- Auditer la couverture réelle du mTLS service mesh
- Comment prévenir une attaque Host header injection
- Condensés cryptographiques : propriétés, constructions et familles
- CRL ou OCSP pour révoquer un certificat
: les deux pages se citent l’une l’autre.
