Jusque-là, nous avons évoqué les propriétés techniques des jetons JWT. Toutefois, en pratique, l’utilisation des JWT requiert de faire très attention aux propriétés de sécurité d’un JWT.
Dans la plupart des cas, les JWT sont utilisés sous la forme de jetons porteurs. Un jeton porteur est un jeton qui peut être utilisé par celui qui le possède. Par conséquent, il suffit à un attaquant d’obtenir un JWT pour commencer à abuser des privilèges associés à ce jeton. Dans cette dernière partie, nous allons brièvement souligner quelques cas d’usage.
Les JWT dans OpenID Connect
Nous avons déjà mentionné l’utilisation de JWT dans OpenID Connect. Le fournisseur délivre un jeton d’identité au client. Le jeton d’identité contient des informations sur l’authentification de l’utilisateur avec le fournisseur. Le jeton d’identité est un jeton JWT, signé avec la clé privée du fournisseur.
OpenID Connect s’est donné beaucoup de mal pour améliorer les propriétés de sécurité du jeton d’identité. Par exemple, le protocole rend obligatoire l’utilisation des revendications « exp », « iss » et « aud ». De plus, le jeton inclut un nonce pour empêcher les attaques par répétition. En raison de ces exigences, il est difficile voire impossible d’abuser d’un jeton d’identité volé.
Les JWTs comme jetons d’accès OAuth 2.0
Un jeton d’accès OAuth 2.0 est un autre cas d’usage intéressant d’un JWT. Ce jeton d’accès donne au client accès à une ressource protégée, comme une API. Les jetons d’accès OAuth 2.0 sont de deux types : les jetons de référence et les jetons self-contained.
Un jeton de référence indique des métadonnées du côté du serveur, conservées par le serveur d’autorisation. Un jeton de référence fonctionne comme un identifiant, de manière semblable à l’identifiant d’une session traditionnelle.
Un jeton self-contained se présente sous la forme d’un JWT. Il contient toutes les métadonnées comme la charge utile. Pour protéger les données, l’émetteur signe le jeton en utilisant une clé privée.
Les jetons OAuth 2.0 traditionnels sont des jetons porteurs. Si l’un d’entre eux est compromis, il peut être utilisé sans restrictions par celui qui le possède. Un jeton de référence compromis peut être évoqué par le serveur d’autorisation. Il est bien plus complexe de révoquer les jetons self-contained.
Aussi, il est fortement recommandé de maintenir la durée de vie des jetons des accès aussi courte que possible. Une durée de vie de quelques minutes ou de quelques heures est assez courante pour les jetons. Il n’est pas recommandé d’avoir des durées de vie de plusieurs jours ou plusieurs mois. Si possible, les jetons d’accès de courte durée devraient être associés à des jetons de rafraichissement pour renforcer la sécurité.
De plus, des ajouts modernes à la spécification portent sur les propriétés du jeton porteur en introduisant des JWT de mécanismes de preuve de possession.
comme objets de session
Des protocoles tels que OpenID Connect et OAuth 2.0 essayent activement de combattre les faiblesses des JWT. Malheureusement, nous observons également plusieurs applications qui incorporent des JWT dans leur architecture, sans tenir compte de ces précautions.
Un exemple concret est une application utilisant des JWT pour stocker le statut d’autorisation sur le client. Cela permet d’utiliser un backend sans statut, et facilite considérablement le déploiement.
Toutefois, ce jeton côté client est un jeton porteur. Sans durée de vie courte ou mécanisme de révocation en place, ce scénario devient extrêmement vulnérable.
Détailler ces questions nous conduirait trop loin dans cet article. Si vous voulez en savoir plus sur ces questions, nous vous conseillons de lire « Stop using JWT for sessions » et « Reference Tokens and Introspection.”