Requête d'autorisation poussée et signée (PAR, JAR)
- Accueil
- Identités, accès & habilitations
- OIDC, SAML et OAuth 2.1 en fédération
- Requête d'autorisation poussée et signée (PAR, JAR)
Requête d’autorisation poussée et signée (PAR, JAR)
Section intitulée « Requête d’autorisation poussée et signée (PAR, JAR) »Dans OAuth tel qu’on le déploie, la requête d’autorisation voyage dans la barre d’adresse du navigateur. Les portées demandées, l’identifiant du client, l’adresse de retour, tout cela traverse l’agent utilisateur en clair, sous forme de paramètres d’URL. C’est simple, et c’est le dernier endroit où l’on souhaiterait confier des données qui déterminent ce qui va être autorisé. Deux extensions corrigent le problème par deux voies différentes : JAR emballe la requête dans un jeton signé, PAR la transmet directement au serveur avant toute redirection. Elles se combinent, et les profils de sécurité exigeants demandent les deux.
Confier un bon de commande au client pour qu’il le porte lui-même au magasin a deux inconvénients : il peut le modifier en route, et tout le monde peut le lire par-dessus son épaule. On peut sceller l’enveloppe, ou faxer la commande au magasin et ne donner au client qu’un numéro de retrait. La seconde méthode est plus simple, et le magasin sait du coup à qui il a affaire avant que le client n’arrive.
→ Lire l’explication complète de la marmotte
Trois défauts de la requête d’autorisation ordinaire
Section intitulée « Trois défauts de la requête d’autorisation ordinaire »La RFC 9126, qui normalise PAR en septembre 2021, ouvre par la liste des problèmes que pose la sérialisation en paramètres d’URL. Elle vaut d’être reprise, parce qu’elle est courte et qu’elle couvre tout le sujet.
Aucune protection d’intégrité ni d’authenticité. « Un attaquant pourrait, par exemple, modifier la portée d’accès demandée ou échanger le contexte d’une transaction de paiement en changeant les valeurs de portée. » La RFC note que des mécanismes permettent au client ou à l’utilisateur de détecter certaines de ces modifications, mais ajoute que « les empêcher tôt dans le processus est une solution plus robuste ». C’est la différence entre un contrôle de cohérence et une impossibilité ; les dégâts que produit une portée modifiée sont illustrés par l’attaque de confusion de scope OAuth.
Aucun mécanisme de confidentialité. HTTPS est requis sur le point d’autorisation, mais « les données de la requête passent par l’agent utilisateur en clair, et les données de la chaîne de requête peuvent fuir par inadvertance dans les journaux de serveur web et vers d’autres sites via le référent ». La RFC précise pourquoi cela compte au-delà du principe : « l’impact d’une telle fuite peut être significatif si des informations personnelles identifiantes ou d’autres données réglementées sont envoyées dans la requête d’autorisation, ce qui peut tout à fait être le cas dans des scénarios d’identité, de banque ouverte et similaires ».
La taille. Les adresses de requête d’autorisation « peuvent devenir assez grandes, en particulier dans les scénarios nécessitant des données d’autorisation à granularité fine, ce qui peut causer des erreurs de traitement ». Ce défaut paraît trivial à côté des deux premiers ; il est en pratique celui qui déclenche l’adoption, parce qu’il casse les déploiements de manière visible.
La RFC balaie au passage la solution de contournement évidente, l’envoi par POST vers le point d’autorisation : elle est optionnelle dans OAuth 2.0 et, même prise en charge, « c’est une option viable pour les applications web conventionnelles mais d’une difficulté prohibitive avec les applications mobiles installées », qui ouvrent l’adresse d’autorisation dans le navigateur du système par une interface de la plateforme. L’argument est d’ingénierie plus que de doctrine, et c’est pour cela qu’il est décisif.
JAR : emballer la requête dans un jeton signé
Section intitulée « JAR : emballer la requête dans un jeton signé »La RFC 9101 attaque le problème par le contenu. Elle définit un objet de requête, qui est un jeton JWT dont les revendications sont les paramètres de la requête d’autorisation, et qui « DOIT contenir tous les paramètres, y compris les paramètres d’extension, utilisés pour traiter la requête d’autorisation », à l’exception de request et request_uri eux-mêmes. Son résumé est d’une clarté qu’on aimerait plus répandue : la sérialisation en paramètres d’URL signifie que « la communication à travers les agents utilisateurs n’est pas protégée en intégrité, donc les paramètres peuvent être altérés ; la source de la communication n’est pas authentifiée ; et la communication à travers les agents utilisateurs peut être surveillée ».
La signature se fait par JWS, dont le fonctionnement est détaillé dans JWS, et le chiffrement optionnel par JWE, détaillé dans JWE. Un point d’ordre compte : « quand la signature et le chiffrement sont tous deux appliqués, le JWT DOIT être signé, puis chiffré », ce qui donne un jeton imbriqué. L’objet signé « DEVRAIT contenir les revendications iss et aud », la valeur d’aud devant être l’identifiant d’émetteur du serveur d’autorisation. Les algorithmes sont choisis par le client parmi ceux que le serveur annonce dans ses métadonnées, et réciproquement déclarés par le client dans ses métadonnées d’enregistrement.
L’objet de requête peut être transmis par valeur, dans un paramètre request, ou par référence, dans un paramètre request_uri que le serveur d’autorisation va chercher. Ce second mode est ce qui a motivé PAR, parce qu’il laissait ouverte la question de savoir comment l’objet arrivait à l’adresse référencée. La RFC 9101 apporte par ailleurs une propriété que PAR seul ne donne pas, et la RFC 9126 le dit explicitement : « les clients exigeant un niveau de sécurité encore plus élevé, en particulier une non-répudiation confirmée cryptographiquement, peuvent utiliser des objets de requête fondés sur JWT en conjonction avec PAR ». Signer la requête, c’est pouvoir prouver plus tard ce qui a été demandé, et par qui.
PAR : pousser la requête avant la redirection
Section intitulée « PAR : pousser la requête avant la redirection »Le mécanisme est d’une simplicité agréable. Le client envoie un POST vers un point d’accès dédié, dont l’adresse « DOIT utiliser le schéma https » et devrait être publiée dans les métadonnées du serveur sous le nom pushed_authorization_request_endpoint. Ce point accepte tous les paramètres applicables au point d’autorisation, y compris les extensions comme PKCE ou les indicateurs de ressource, et « PEUT également prendre en charge l’envoi de l’ensemble des paramètres sous forme d’objet de requête ». Un seul paramètre est proscrit : request_uri, pour des raisons évidentes de circularité.
Les règles d’authentification du client sont celles du point de jeton, et c’est le point central. En cas de succès, le serveur répond 201 avec deux membres : un request_uri, qui est « une référence à usage unique vers les données de requête correspondantes », et un expires_in dont la RFC précise la plage attendue, « typiquement relativement courte, par exemple entre 5 et 600 secondes ». Trois exigences encadrent cette référence : son format est libre mais elle « DOIT contenir une partie générée par un algorithme pseudo-aléatoire cryptographiquement fort, tel qu’il soit informatiquement infaisable de prédire ou de deviner une valeur valide » ; elle « DOIT être liée au client qui a posté la requête » ; et il n’y a « aucun besoin de rendre les données de requête disponibles à d’autres parties via cette adresse », remarque qui mérite d’être relue par qui serait tenté d’en faire un service de consultation. Les propriétés attendues de la source d’aléa sont celles de produire de l’aléa utilisable.
L’utilisateur est ensuite redirigé vers le point d’autorisation avec, pour seuls paramètres, l’identifiant du client et ce request_uri. La barre d’adresse ne contient donc plus rien d’intéressant, ce qui règle d’un coup les trois défauts initiaux. La RFC note le gain de confidentialité dans ses considérations de vie privée : PAR « peut améliorer la vie privée en réduisant le potentiel de divulgation d’information par inadvertance, puisqu’il fait passer les données de requête d’autorisation directement entre le client et le serveur d’autorisation sur une connexion sécurisée, dans le corps du message d’une requête HTTP, plutôt que dans le composant de requête d’une adresse qui traverse l’agent utilisateur en clair ».
Ce que PAR change pour l’exploitation
Section intitulée « Ce que PAR change pour l’exploitation »Le bénéfice le moins évident est le plus utile, et il n’a rien à voir avec les paramètres : « PAR permet au serveur d’autorisation d’authentifier le client avant que toute interaction avec l’utilisateur n’ait lieu. La confiance accrue dans l’identité du client pendant le processus d’autorisation permet au serveur d’autorisation de refuser les requêtes illégitimes bien plus tôt dans le processus, ce qui peut prévenir les tentatives d’usurpation de client ou les manipulations et usages abusifs d’une requête d’autorisation. » Autrement dit, un client contrefait est arrêté avant qu’un écran de consentement ne soit affiché à qui que ce soit. C’est une différence de nature : la détection cesse de reposer sur la vigilance de l’utilisateur.
Conséquence pratique immédiate, et elle fera plaisir aux équipes d’exploitation : la correspondance exacte des adresses de redirection peut être assouplie. La RFC rappelle que les bonnes pratiques de sécurité OAuth et la spécification OAuth 2.1 exigent une correspondance exacte du redirect_uri avec l’ensemble enregistré, ce qui est « un moyen de détection précoce des tentatives d’usurpation de client » et prévient la fuite de jetons et la redirection ouverte, mais ajoute l’inconvénient : « cela peut rendre la gestion des clients plus lourde, puisque l’adresse de redirection est typiquement la partie la plus volatile d’une politique de client ». Avec PAR, pour des clients qui se sont authentifiés, l’exigence « PEUT être assouplie », puisque « le serveur d’autorisation authentifie le client avant que le processus d’autorisation ne commence et s’assure ainsi qu’il interagit avec le client légitime ». Il reste libre d’imposer un préfixe ou de n’autoriser qu’un paramètre de requête variable. On échange une contrainte de configuration contre une authentification, ce qui est le bon sens même.
Côté gestion, un détail d’interopérabilité mérite d’être connu parce qu’il casse des intégrations : pour l’authentification du client par assertion JWT, « il existe une ambiguïté potentielle quant à la valeur d’audience appropriée ». La RFC tranche en recommandant l’identifiant d’émetteur du serveur d’autorisation, mais exige des serveurs qu’ils acceptent, « afin de faciliter l’interopérabilité », leur identifiant d’émetteur, l’adresse de leur point de jeton ou celle de leur point PAR. Un client qui ne passe pas l’authentification sur l’un de ces trois choix a trouvé un serveur non conforme, et c’est une information utile en salle de recette.
Les cinq attaques que la spécification traite
Section intitulée « Les cinq attaques que la spécification traite »La section de considérations de sécurité de la RFC 9126 est courte et entièrement composée de choses à faire.
Devinette de l’adresse de requête. Un attaquant pourrait tenter de deviner et de rejouer une valeur valide pour usurper le client correspondant ; d’où l’exigence d’entropie déjà citée, que la RFC renvoie aux considérations de JAR sur ce point.
Redirection ouverte. Un attaquant pourrait enregistrer une adresse de redirection pointant vers un site qu’il contrôle, pour obtenir des codes d’autorisation ou attaquer l’utilisateur. La règle est impérative et c’est la contrepartie exacte de l’assouplissement vu plus haut : « le serveur d’autorisation NE DOIT accepter de nouvelles adresses de redirection dans la requête d’autorisation poussée que de clients authentifiés ». Assouplir la correspondance sans authentifier le client serait précisément l’erreur à ne pas commettre.
Rejeu de l’objet de requête. Une adresse de requête capturée sur une requête légitime peut être rejouée ; « pour faire face à de telles attaques, le serveur d’autorisation DEVRAIT rendre les adresses de requête à usage unique ». C’est la raison de la mention « référence à usage unique » dans la définition de la réponse.
Changement de politique du client. La politique du client peut changer entre le dépôt de l’objet de requête et son usage. Il est donc « recommandé que le serveur d’autorisation vérifie le paramètre de requête contre la politique du client au moment du traitement de la requête d’autorisation », et non seulement au dépôt. Un contrôle fait une seule fois, en amont, est un contrôle périmé.
Permutation d’adresses de requête. La plus intéressante : un attaquant capture l’adresse de requête d’une requête et la substitue dans une autre. L’exemple donné est édifiant : « dans le contexte d’OpenID Connect, un attaquant pourrait remplacer une adresse de requête demandant un niveau élevé d’assurance d’authentification par une qui en requiert un niveau plus faible ». La parade n’est pas dans PAR mais chez le client : « les clients DEVRAIENT faire usage de PKCE, d’un paramètre state unique ou du paramètre nonce d’OpenID Connect dans l’objet de requête poussé pour prévenir cette attaque ». PKCE reste donc nécessaire, et son fonctionnement est décrit dans le flux OAuth avec PKCE en une page et dans les pièges OAuth 2.1. La notion de niveau d’assurance que cette attaque vise à dégrader est l’objet de les niveaux d’assurance d’authentification.
Reste à savoir qui exige ces deux extensions. Les profils de sécurité de la banque ouverte les imposent, et c’est le sens de l’exigence combinée exposée dans FAPI 2.0 : requête poussée obligatoire, jeton contraint par l’expéditeur par DPoP ou par liaison au certificat client, et interdiction de ce qui reste optionnel ailleurs. Pour une organisation qui n’a pas d’obligation sectorielle, le bon ordre d’adoption est celui du coût : PAR d’abord, parce qu’il ne demande qu’un appel supplémentaire et qu’il résout les trois défauts initiaux ; JAR ensuite, si la non-répudiation de la requête a une valeur, c’est-à-dire s’il faut pouvoir prouver, après coup, ce qui avait été demandé.
- RFC 9126 : OAuth 2.0 Pushed Authorization Requests, T. Lodderstedt, B. Campbell, N. Sakimura, D. Tonge, F. Skokan, IETF, septembre 2021.
- RFC 9101 : The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR), N. Sakimura, J. Bradley, M. Jones, IETF, août 2021.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Sans protection d’intégrité de la requête d’autorisation, les portées demandées et le contexte d’une transaction se modifient dans la barre d’adresse du navigateur, et le consentement obtenu ne porte pas sur ce que le client avait demandé. Sans sortir les paramètres de l’adresse, les données qu’ils contiennent fuient dans les journaux de serveur web et vers des sites tiers par l’en-tête de référent, ce qui, pour une requête d’identité ou de paiement, est une divulgation de données réglementées. Sans authentification du client avant l’interaction, un client contrefait obtient l’affichage d’un écran de consentement, et la détection repose sur la vigilance de l’utilisateur. Sans référence à usage unique et à forte entropie, l’adresse de requête poussée se devine ou se rejoue. Sans nouvelle vérification de la politique du client au moment de l’autorisation, un contrôle effectué au dépôt reste valide alors que la politique a changé. Et sans PKCE ni état unique dans l’objet poussé, une adresse de requête se substitue à une autre, par exemple pour abaisser le niveau d’assurance d’authentification exigé.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Quand une application vous demande de vous connecter avec un compte tiers, elle vous envoie vers le site de ce tiers en plaçant tous les détails de sa demande dans l’adresse internet : qui demande, quelles permissions, où revenir ensuite. Cette adresse passe par votre navigateur, ce qui crée trois problèmes. Elle peut être modifiée en route, par exemple pour élargir les permissions demandées. Elle peut être lue et recopiée, notamment dans les journaux des serveurs et dans les informations transmises aux sites suivants. Et elle devient parfois trop longue pour fonctionner.
Deux solutions existent. La première consiste à mettre tous ces détails dans un petit document signé, et éventuellement chiffré, que le navigateur transporte sans pouvoir le modifier. La seconde, plus simple, consiste à ne rien faire transporter du tout : l’application envoie sa demande directement au site tiers, par une connexion entre serveurs, et reçoit en échange un numéro de retrait valable quelques dizaines de secondes. Le navigateur ne transporte plus que ce numéro.
La seconde méthode apporte un bénéfice inattendu. Comme l’application s’adresse directement au site tiers, celui-ci peut l’authentifier avant même que vous n’arriviez. Une application contrefaite est donc rejetée avant qu’un écran de consentement ne vous soit présenté, ce qui vaut mieux que de compter sur votre vigilance. En contrepartie, le site tiers peut se montrer plus souple sur un réglage habituellement rigide, la liste des adresses de retour autorisées, puisqu’il sait à qui il parle.
Quatre précautions accompagnent le dispositif, et les documents de référence les énoncent clairement. Le numéro de retrait doit être imprévisible, à usage unique, et de durée très courte. Les nouvelles adresses de retour ne doivent être acceptées que de la part d’applications authentifiées. La politique applicable doit être revérifiée au moment où la demande est utilisée, et pas seulement au moment où elle est déposée. Et l’application doit continuer d’utiliser les protections existantes, faute de quoi un attaquant peut échanger un numéro de retrait contre un autre, par exemple pour abaisser le niveau de vérification d’identité exigé.
À 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.
- 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.
- OIDC, SAML et OAuth 2.1 en fédérationComparer OIDC et SAML, déployer OAuth 2.1 sans confusion, et gouverner la durée de vie, la portée et la révocation des jetons.
- Découverte et enregistrement dynamique de clientComment un client obtient seul les adresses d'un fournisseur d'identité puis s'y enregistre sans intervention humaine, l'usurpation d'émetteur que cela rend possible, et les contrôles qui la ferment.
Pages voisines
La citent
Requête d'autorisation poussée et signée (PAR, JAR)
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
- Pièges OAuth 2.1 : PKCE, redirections et scopes
- Jetons d'accès liés au certificat client : ce que mTLS ajoute à OAuth
- Niveaux d'assurance d'authentification : ce qu'il faut pour monter d'un cran
- Attaque par confusion de scope OAuth
- JWE : chiffrer un jeton JSON sans se tromper
- JWS : signer et sécuriser vos échanges JSON
- Le flux OAuth avec PKCE en une page
- Produire de l’aléa utilisable en cryptographie
: les deux pages se citent l’une l’autre.
