Jetons et pièges : 7 vulnérabilités courantes d’OAuth (et leurs solutions)
Dans le monde des applications web modernes, le protocole OAuth agit comme notre gardien de confiance, facilitant les connexions sans mot de passe et le partage sécurisé des données. Mais sa grande flexibilité, pensée pour répondre à une multitude de cas d’usage, est aussi son talon d’Achille. Une simple erreur dans la validation d’une URI ou l’absence d’un paramètre de vérification peut transformer un échange de jetons robuste en une porte grande ouverte aux hackers.
Dans cet article, nous passerons en revue les vulnérabilités d’OAuth les plus fréquentes, nous expliquerons leur fonctionnement et nous verrons quelles solutions mettre en place pour renforcer vos défenses avant qu’un cybercriminel ne s’infiltre.
Qu’est-ce qu’OAuth ?
OAuth (abréviation pour Open Authorization) est un protocole standard de l’industrie qui permet une délégation d’accès sécurisée, basée sur des jetons, à des ressources protégées, sans avoir à partager les identifiants de l’utilisateur avec des applications tierces. Plutôt que de demander aux utilisateurs de transmettre leur mot de passe, OAuth utilise des jetons d’accès (des identifiants temporaires et limités dans leur portée) que les applications clientes échangent pour obtenir les autorisations nécessaires à l’accès à des API ou des services au nom de l’utilisateur.
Cette séparation des rôles, (entre le propriétaire de la ressource, le serveur de ressources, l’application cliente et le serveur d’autorisation), réduit la surface d’attaque, car les identifiants de connexion sont moins exposés et permet un contrôle précis des opérations qu’un client peut effectuer. En pratique, OAuth est un pilier fondamental des scénarios d’identité fédérée modernes, des intégrations entre applications web et mobiles, ainsi que des architectures orientées microservices. Il garantit une interopérabilité standardisée et traçable entre les systèmes.
Pourquoi OAuth est-il vulnérable ?
Les vulnérabilités d’OAuth ne proviennent pas tant d’un défaut dans la conception du protocole que de sa complexité et flexibilité intrinsèques, qui imposent une forte exigence de rigueur aux développeurs lors de sa mise en œuvre. OAuth implique plusieurs parties prenantes (propriétaires de ressources, clients, serveurs d’autorisation et serveurs de ressources), chacune avec ses propres points de terminaison et paramètres (redirect_uris, scopes, state, code_challenge, etc.). Cette complexité signifie qu’il existe de nombreux réglages sensibles à bien configurer : correspondance exacte des URI de redirection, limitation stricte des permissions, utilisation correcte de PKCE et bien d’autres. La moindre négligence peut suffire à ouvrir la voie à des attaques visant à détourner des codes ou des jetons d’accès.
En réalité, la puissance d’OAuth, (l’accès délégué reposant sur des jetons), s’appuie sur de nombreux mécanismes de contrôle. Mais lorsque les développeurs ou les architectes négligent certaines vérifications essentielles, (comme la validation stricte des URI, la vérification du paramètre state, ou le contrôle des signatures sur les jetons d’identification), des hackers peuvent exploiter ces failles de configuration. Ce n’est donc pas le protocole OAuth lui-même qui est vulnérables, mais sa flexibilité, ainsi que la diversité des paramètres et des flux disponibles, qui le rendent propice aux erreurs de mise en œuvre, sources de vulnérabilités exploitables dans des attaques réelles.
Sept vulnérabilités courantes d’OAuth
1. Redirection ouverte et manipulation de l’URI de redirection
Fonctionnement :
- Pendant le processus d’autorisation, les clients OAuth enregistrent une ou plusieurs URI de redirection (appelées aussi callback endpoints) auprès du serveur d’autorisation. Si ces URI sont trop permissives (par exemple, https://example.com/*) ou mal vérifiées par le serveur d’autorisation, un hacker peut fabriquer une URL qui pointe vers un endpoint malveillant.
- Le hacker pousse l’utilisateur à cliquer sur un lien du type :
- https://auth-server.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=https://example.com/evil&state=XYZ
- Si le serveur d’autorisation ne vérifie pas rigoureusement que l’URL fournie (https://example.com/evil) correspond exactement à l’URL de redirection enregistrée (https://example.com/callback), il peut transmettre un code d’autorisation (ou jeton) vers un endpoint contrôlé par le hacker.
- Ce dernier pourra échanger ce code contre un jeton d’accès, lui permettant d’accéder de manière non autorisée aux données de la victime.
Contremesures :
- Appariement exact des URI de redirection : configurez le serveur d’autorisation pour qu’il n’accepte que des URI de redirection strictement identiques (ou explicitement enregistrées à l’avance). L’utilisation de caractères génériques (Wildcards) est à proscrire, sauf nécessité absolue et dans ce cas, uniquement sur les sous-domaines, après une évaluation rigoureuse des risques.
- Validation à l’exécution : lors de chaque requête d’autorisation, le serveur doit comparer l’URI de redirection (redirect_uri) octet par octet avec la liste blanche définie lors de l’enregistrement du client.
- Imposer l’usage de HTTPS : n’autorisez que des URI de redirection protégées par TLS (HTTPS), afin d’éliminer les variantes de type “man-in-the-middle” qui exploiteraient des versions HTTP non sécurisées d’URI valides.
2. Absence ou faiblesse des protections CSRF/protection du paramètre state
Fonctionnement :
- Les flux Authorization Code et Implicit d’OAuth sont vulnérables aux attaques de type Cross-Site Request Forgery (CSRF) si le paramètre state est omis ou mal lié à la session de l’utilisateur.
- Un hacker peut générer à l’avance une URL d’autorisation valide avec son propre client_id et redirect_uri, puis inciter un utilisateur connecté à cliquer dessus. Comme le navigateur de la victime dispose déjà d’une session active avec le fournisseur OAuth, ce dernier peut émettre un code d’autorisation lié au point de redirection du hacker.
- Sans vérification rigoureuse du paramètre state, le client ne peut pas faire la différence entre une réponse légitime et une réponse malveillante, ce qui peut entraîner une association involontaire du compte de la victime avec le service du hacker (login CSRF) ou permettre au cybercriminel d’obtenir un code d’autorisation au nom de la victime.
Contremesures :
- Toujours générer un paramètre state unique par session : lors de l’envoi de la requête d’autorisation initiale, le client doit générer une valeur state aléatoire de manière cryptographiquement sécurisée, la stocker dans la session utilisateur, puis l’inclure dans la requête.
- Valider strictement le paramètre state lors du retour : à la réception du retour OAuth, vérifier strictement que la valeur du paramètre state correspond exactement à celle stockée en session.
- Utiliser les cookies SameSite : configurer les cookies de session avec l’attribut SameSite=Strict|Lax afin de limiter les risques de requêtes inter-origines transportant un contexte d’authentification.
3. Flux implicite et absence de PKCE (Proof Key for Code Exchange)
Fonctionnement :
- Dans le flux implicite classique, aujourd’hui obsolète dans la majorité des cas d’usage, le jeton d’accès est directement renvoyé dans l’URI de redirection, ce qui l’expose au navigateur et augmente considérablement les risques. L’application cliente (souvent une application monopage, ou SPA) reçoit le jeton d’accès via le fragment de l’URI, ce qui permet à un hacker, via un script malveillant ou un réseau compromis, d’intercepter ce jeton.
- Le flux d’autorisation avec code (Authorization Code Flow), plus sécurisé, est un flux OAuth en deux étapes : le client obtient d’abord un code d’autorisation temporaire, puis l’échange contre un jeton d’accès, ce qui renforce la sécurité (puisque les jetons ne transitent pas via le navigateur). Cependant, si le client n’implémente pas PKCE, un hacker capable d’intercepter la redirection (par exemple via une application malveillante utilisant le même client_id) peut capturer le code d’autorisation et l’échanger contre un jeton d’accès, accédant ainsi illégitimement aux ressources de l’utilisateur.
Contremesures :
- Utiliser le flux d’autorisation avec code + PKCE : chaque client public (application mobile, SPA, application pour poste de travail) doit générer, à chaque requête, une valeur de vérification (code verifier) et envoyer un code challenge. Ainsi, même si un hacker intercepte ce code, il ne pourra pas l’échanger sans disposer de la valeur de vérification d’origine.
- Abandonner le flux implicite : les bonnes pratiques actuelles déconseillent l’usage du flux implicite. Les serveurs d’autorisation et les clients doivent être configurés pour utiliser PKCE par défaut, en ne retournant que des codes d’autorisation (les jetons étant transmis via un canal serveur à serveur, ou back-channel).
4. Validation inadéquate des périmètres d’autorisation et droits excessifs
Fonctionnement :
- Lorsqu’un client demande des autorisations, il peut solliciter des périmètres d’accès (scopes) bien plus étendus que nécessaire. Si le propriétaire de la ressource accorde involontairement tous ces périmètres, le client (ou un hacker l’ayant compromis), pourra accéder à des données ou effectuer des actions bien au-delà du besoin réel.
- Des hackers peuvent tromper les utilisateurs via l’ingénierie sociale ou le phishing pour leur faire approuver des périmètres à privilèges élevés, puis exploiter les jetons pour élever leurs privilèges ou accéder à d’autres ressources.
Contremesures :
- Principe du moindre privilège (PoLP) : demandez toujours le minimum de périmètres d’accès nécessaires pour une fonctionnalité donnée. Analysez les parcours UI/UX afin de vous assurer que les utilisateurs comprennent exactement à quelles données ils consentent à donner accès.
- Contrôle côté serveur : le serveur de ressources doit vérifier que le périmètre d’autorisation contenu dans le jeton correspond bien à l’opération demandée. Rejetez toute requête API dont le périmètre est insuffisant ou absent.
- Granularité des périmètres : définissez des périmètres fins et spécifiques lors de l’enregistrement des API (ex : factures:lecture vs factures:écriture, plutôt qu’un unique “factures”). Cela empêche l’utilisateur d’octroyer involontairement des droits complets quand seul un accès en lecture est requis.
5. Fuite de jetons via un stockage ou un transport non sécurisé
Fonctionnement :
- Le stockage local, le stockage de session ou les cookies sans attribut HttpOnly peuvent être accessibles à du JavaScript malveillant via une vulnérabilité XSS (Cross-Site Scripting). Si les jetons d’accès (ou de rafraîchissement) sont conservés dans ces emplacements, un hacker peut les voler et exécuter des requêtes aux API comme s’il était l’utilisateur.
- Transmettre des jetons via des canaux non chiffrés (HTTP) ou avec une configuration TLS mal sécurisée (ex : certificats auto-signés acceptés sans vérification) expose les jetons à des interceptions réseau.
Contremesures :
- Utiliser des cookies sécurisés avec l’attribut HttpOnly : stockez les jetons dans des cookies sécurisés et définissez l’attribut HttpOnly afin d’empêcher les scripts côté client d’y accéder ou de les modifier.
- Imposer TLS sur l’ensemble des communications : tous les points de terminaison (autorisation, jeton ressource) doivent obligatoirement utiliser HTTPS avec des chiffrements robustes. Activez également HTTP Strict Transport Security (HSTS) pour éviter les attaques par rétrogradation.
- Utiliser des jetons d’accès de courte durée + jetons de rafraîchissement rotatifs : Générez des jetons avec une durée de vie très limitée (ex : 5 à 15 minutes) et renouvelez automatiquement le jeton de rafraîchissement à chaque utilisation. Cela réduit considérablement la fenêtre d’attaque en cas de compromission d’un jeton.
6. Révocation manquante ou inefficace des jetons
Fonctionnement :
- Lorsqu’un utilisateur révoque l’accès à une application (par exemple depuis son tableau de bord), si le serveur d’autorisation ne révoque pas immédiatement ou ne met pas sur liste noire les jetons d’accès ou de rafraîchissement existants, le client peut continuer à fonctionner comme s’il était toujours autorisé. En cas de compromission du client, un hacker peut ainsi envoyer des requêtes aux API indéfiniment.
- Certaines implémentations ne propagent pas la révocation aux serveurs de ressources en aval, ce qui maintient en validité des jetons obsolètes.
Contremesures :
- Mettre en place un point de terminaison de révocation : conformez-vous à la RFC 7009 en fournissant un endpoint de révocation permettant aux clients (ou utilisateurs) d’invalider explicitement les jetons d’accès et de rafraîchissement.
- Durées de vie courtes des jetons + validation continue : au-delà de la révocation, configurez les serveurs de ressources pour vérifier les métadonnées des jetons (par exemple via des endpoints d’introspection) pour chaque requête API, ou maintenez une liste noire des jetons révoqués.
- Notifier les services tiers : dans les configurations fédérées (ex : systèmes pointés SAML <→ OAuth), assurez-vous que les événements de révocation informent tous les fournisseurs en aval afin d’empêcher l’utilisation de jetons obsolètes ailleurs.
7. Implémentations OAuth développées en interne ou obsolètes
Fonctionnement :
- Les développeurs tentent parfois de créer leur propre solution ou utilisent des bibliothèques obsolètes qui ne sont pas pleinement conformes aux dernières bonnes pratiques OAuth 2.1 et OpenID Connect. Cela peut engendrer des erreurs subtiles, comme la non-validation des signatures des id_token, l’ignorance des revendications d’audience (aud), ou la réutilisation de secrets clients statiques dans des clients publics.
- Le code personnalisé peut accepter des paramètres fournis par l’utilisateur sans une validation correcte, ou omettre des vérifications obligatoires (par exemple, ne pas vérifier le nonce en OIDC), ce qui ouvre la porte à des attaques de type relecture, substitution de jetons, ou usurpation non autorisée.
Contremesures :
- Adopter des bibliothèques et frameworks bien maintenus : privilégiez les SDK soutenus par des éditeurs reconnus ou audités par la communauté (par exemple, les bibliothèques clientes Auth0, les modules OAuth de Spring Security) qui sont régulièrement mis à jour selon les évolutions des spécifications OAuth 2.1 et IANA.
- Effectuer des revues de code rigoureuses et des modélisations de menaces : pour toute intégration personnalisée (par exemple, un fournisseur d’identité tiers), réalisez une analyse des menaces qui détaille chaque étape du flux et garantit que tous les paramètres (iss, aud, nonce, exp, state) sont correctement vérifiés.
- Se tenir à jour avec les RFC et les avis de sécurité : les vulnérabilités liées à OAuth (CVE) et les meilleures pratiques évoluent rapidement. Abonnez-vous à la liste de diffusion de sécurité OAuth et procédez régulièrement à des audits de votre configuration en vous référant aux dernières recommandations IETF (ex : PKCE obligatoire, dépréciation du flux implicite, exigence de la preuve de possession lorsque possible).
Points clés à retenir sur les vulnérabilités OAuth
- Pour déployer OAuth de manière sécurisée et fiable, appliquez une validation rigoureuse des URI de redirection, des paramètres state et des signatures de jetons ; adoptez PKCE pour tous les clients publics ; et respectez le principe du moindre privilège dans les demandes de périmètres d’accès.
- Assurez le stockage et une transmission sécurisée des jetons (privilégiez les cookies HttpOnly au stockage local) et mettez en place la révocation de jetons avec une introspection continue.
- Utilisez des bibliothèques OAuth reconnues par la communauté, suivez les évolutions des recommandations IETF/OAuth 2.1 et maintenez une journalisation et une surveillance efficace pour détecter rapidement toute utilisation abusive.
En traitant de manière proactive ces vulnérabilités OAuth courantes, les organisations réduisent significativement les risques de vol d’identifiants, d’accès non autorisé aux API et de fuites massives de données liées à des intégrations OAuth défaillantes.
Détectez les vulnérabilités OAuth avec le PTaaS d’Outpost24
Dans un environnement de menaces en constante évolution, se reposer uniquement sur des évaluations manuelles périodiques peut laisser des erreurs critiques de configuration OAuth non détectées pendant des semaines, voire des mois. Grâce à la solution Pen-Testing as a Service (PTaaS) d’Outpost24, les équipes de sécurité bénéficient d’un scan continu, principalement manuel et réalisé par des experts humains, ciblant les derniers vecteurs d’attaque OAuth, identification des redirections ouvertes, implémentations PKCE incorrectes, sur-provisionnement des paramètres d’accès et failles exploitées en conditions réelles.
Commencez à sécuriser en continu vos déploiements OAuth et réduisez les risques sur vos applications web et mobiles. Demandez dès aujourd’hui une démonstration de la solution PTaaS d’Outpost24.
Pour une visibilité et une sécurité encore plus complète de votre surface d’attaque, découvrez comment la solution CyberFlex d’Outpost24 combine PTaaS et la Gestion de la Surface d’Attaque Externe (EASM).