Introduit il y a un peu plus de 10 ans par Forrester, le Zero Trust est une philosophie de sécurité qui part du postulat que la menace cyber est omniprésente, aussi bien à l’extérieur qu’à l’intérieur du SI, et propose en conséquence une stratégie de gestion des accès basée sur trois principes élémentaires : vérifier explicitement, minimiser les privilèges, surveiller constamment
Figure 1 : Les trois principes fondamentaux du modèle Zero Trust
Ces principes sont aujourd’hui bien connus mais leur mise en œuvre concrète demeure un défi pour beaucoup d’organisations.
Il n’existe et n’existera pas de produit unique permettant d’implémenter un modèle Zero Trust. Les architectures d’implémentation sont par ailleurs multiples. Pour les accès utilisateurs, le Zero Trust peut être implémenté à l’aide de deux principaux modèles d’architecture (qui ne s’opposent pas et peuvent être complémentaires) :
- Un modèle utilisant un élément d’infrastructure en coupure, par exemple dans une approche de type Secure Access Service Edge (SASE). Il va contrôler dynamiquement l’accès réseau aux ressources du SI (l’identité et la posture de l’utilisateur étant bien évidemment utilisées pour prendre la décision).
- Une approche où seul l’identité est utilisée pour faire la coupure : l’accès aux ressources du SI est conditionné par la présentation de preuves d’authentification et d’autorisation. Dans cette approche, le contrôle d’accès est réalisé par un Identity provider (gestionnaire d’identité ou IdP) et par les ressources cibles elles-mêmes.
C’est ce deuxième type d’architecture qui fera l’objet de cet article. Nous nous intéresserons en particulier à une implémentation utilisant Azure Active Directory (AAD) comme Identity Provider.
Avant de comprendre comment l’Identity Provider peut permettre d’implémenter le Zéro Trust, un peu de théorie sur les mécanismes de la gestion des accès basée sur des jetons.
La gestion des accès basée sur AAD : une histoire de jetons
La gestion des accès basée sur AAD reprend les principes du schéma d’accès faisant intervenir un Identity Provider, à savoir un service auquel la ressource cible délègue la gestion du cycle de vie des identités des utilisateurs et leur authentification.
Dans ce schéma, l’accès d’un utilisateur à une ressource nécessite la présentation d’un laisser-passer valide délivré par l’Identity Provider après authentification de l’utilisateur et (potentiellement) vérification de son habilitation à accéder à la ressource cible. Ces laisser-passer sont appelés jetons ou tokens et sont signés cryptographiquement pour se prémunir de l’utilisation de faux jetons.
Au fait, un Token c’est quoi ? C’est une chaine de caractères contenant diverses informations que l’on appelle des clauses, et qui se transmet par exemple par requête HTTPs.
AAD, en tant que fournisseur d’identité, délivre trois types de jetons appelés Security Tokens :
ID Token: Preuve de l’authentification de l’utilisateur. Il contient des informations sur l’identité de l’utilisateur et sur le contexte d’authentification. Il n’est associé à aucune ressource en particulier et n’intervient pas dans le contrôle d’accès.
Access Token: Laisser-passer autorisant l’accès à une ressource en particulier. Il peut contenir des attributs ou claims permettant à la ressource cible d’affiner le contrôle d’accès. Dans le cas d’Azure AD, il s’agit de jeton autoporteur(*) (JWT) : donc non révocable après émission. Sa durée de vie est d’une heure en moyenne. Autrement dit, un Access Token est valide tant que sa durée de vie n’a pas expirée.
(*)une autre implémentation d’OAuth aurait pu être avec des jetons opaques nécessitant d’interroger l’Authorization server pour connaitre le détail. Ce type d’implémentation permettant une révocation plus facile. Ce n’est pas le choix fait par Microsoft.
Refresh Token: jeton fourni en même temps que l’Access Token, Il permet d’obtenir une nouvelle paire Access Token/Refresh Token après expiration de l’Access Token précédent, sans réauthentification explicite de l’utilisateur. Il permet également de récupérer des Access Tokens pour d’autres ressources sans authentification explicite de l’utilisateur. Dans le cadre d’Azure AD, sa une durée de vie est de 90j ou 24h pour les Single Page Applications et contrairement à l’acces Token, il est possible de le révoquer avant son expiration.
A noter que Microsoft a défini un quatrième type de jeton, le Primary Refresh Token, permettant de faire du Single Sign-On entre applications sur un device donné. Ce jeton ne sera pas évoqué dans la suite du document par souci de simplification.
A présent, il nous reste à comprendre comment ces différents Tokens circulent d’acteur en acteur !
Accès initial à la ressource cible
Lors de l’accès initial, nous supposons qu’il n’y aucun jeton en cours de validité : pas d’Access Token pour la ressource cible ni de Refresh Token. Quand l’utilisateur voudra accéder à la ressource cible, il sera redirigé vers AAD pour être authentifié (et éventuellement autorisé).
Figure 2 : Cinématique d’obtention d’une paire Access Token/Refresh Token lors de l’accès initial à la ressource
L’Access Token obtenu sera inclus dans chacune des requêtes destinées à la ressource cible. Celle-ci les traitera tant que l’Access Token n’aura pas expiré.
Renouvellement du droit d’accès à la ressource
Après expiration de l’Access Token initial, le Refresh Token sera utilisé pour récupérer silencieusement, sans intervention de l’utilisateur, une nouvelle paire Access Token/Refresh Token
Figure 3 : Cinématique de maintien de la session d’accès via le renouvellement de la paire Access Token/Refresh Token
Dans un modèle de gestion des accès faisant intervenir un Identity Provider comme AAD, nous constatons que les jetons sont les clés du château et l’Identity Provider en est le gardien.
Regardons à présent dans quelle mesure ce modèle de gestion des accès permet d’implémenter les principes du Zero Trust pour les applications qui s’appuient sur AAD pour gérer leur sessions de connexion.
Les jetons : des supports de confiance implicite vulnérables
En examinant le fonctionnement de la gestion des accès basée sur Azure AD, nous constatons que :
- L’accès à toute ressource déléguant la gestion des accès nécessite une preuve d’authentification et d’autorisation, à travers la présentation d’un Access Token valide, et ce indépendamment de l’origine réseau de l’accès.
- Un Access Token ne donne accès qu’à une seule ressource. L’accès à une ressource différente nécessite l’obtention d’un Access Token dédié auprès de l’Identity Provider
- Le Refresh Token permet d’obtenir des Access Tokens pour toutes les ressources auxquelles l’utilisateur est autorisé
L’application des principes du Zero Trust est à ce stade partielle et perfectible :
- Par défaut, la délivrance de l’Access Token se fait contre une authentification basique (login et mot de passe)
- La validité de l’Access Token est décorrélé du contexte. Il est utilisable pendant sa période de validité indépendamment des signaux de compromission potentiels détectés
- L’Access Token peut être renouvelé sans vérification que le contexte d’authentification n’ait pas changé
Le Conditional Access (CA) renforce les conditions de délivrance des Tokens et la sécurité de la session
Le Conditional Access (CA) est une fonction d’AAD nécessitant une licence AAD Premium P1 ou M365 Business Premium permettant la prise en compte du contexte dans la gestion des accès.
Grâce au CA, il est possible d’intégrer dans la décision d’autorisation d’un accès un ensemble de signaux liés à l’identité de l’utilisateur, au terminal utilisé, à la ressource cible, au contexte d’accès et/ou au niveau de risque.
Le CA permet par ailleurs d’appliquer des décisions d’autorisation non binaires. Ainsi un accès réalisé dans un certain contexte peut être autorisé sous conditions, celles-ci visant à compenser et réduire le niveau de risque associé au contexte d’accès.
Figure 4 : Principe de fonctionnement du Conditional Access
La délivrance d’un Access Token peut ainsi être conditionnée par une authentification renforcée à double facteur, ce qui aide à se prémunir d’un accès non autorisé découlant d’un vol d’identifiants.
Le CA propose d’autres mécanismes permettant de conditionner l’utilisation des jetons. Nous nous intéresserons ici à deux mécanismes en particulier : la Sign-In Frequency (SIF) et le Continuous Access Evaluation (CAE).
La Sign-In Frequency : moyen d’action sur la fréquence d’authentification explicite de l’utilisateur
La Sign-In Frequency permet de définir une durée maximale au-delà de laquelle l’utilisateur doit explicitement se réauthentifier après avoir été initialement autorisé à accéder à la ressource cible.
Au-delà de cette durée, le Refresh Token ne peut pas être utilisé pour renouveler implicitement la paire Access Token/Refresh Token.
La SIF est ainsi un moyen de limiter dans le temps la confiance implicite accordée aux Refresh Tokens.
Le fonctionnement du mécanisme est illustré ci-dessous, pour une SIF définie à 90 minutes.
Figure 5 : Illustration du fonctionnement de la Sign-in Frequency
On notera que la SIF n’a aucun effet sur la validité des Access Tokens déjà émis. Un Access Token qui n’a pas encore expiré pourra toujours être utilisé pour accéder à la ressource associée, même après expiration de la durée maximale définie par la SIF. La SIF n’intervient en effet que pour empêcher un renouvellement implicite des Access Tokens déjà émis ou l’obtention implicite de nouveaux Access Tokens. Pour pouvoir agir sur les Access Tokens déjà émis, il faut se tourner vers le Continuous Access Evaluation (CAE).
Le Continuous Access Evaluation (CAE), un moyen de lier la validité des Access Tokens au contexte
Le CAE est une fonctionnalité du CA disponible depuis janvier 2022 qui permet la prise en compte du contexte tout au long de la session d’accès et pas seulement au moment de l’autorisation initiale, de sorte à pouvoir forcer un renouvellement de l’Access Token déjà émis en réponse à certains signaux, notamment des signaux suggérant une compromission.
Figure 6 : Types de signaux pouvant forcer le renouvellement de l’Access Token
Pour ce faire, le CAE nécessite un lien de communication entre AAD et la ressource cible permettant de notifier à celle-ci les signaux nécessitant une réauthentification et de récupérer les politiques d’accès conditionnel définies la concernant. Quand la ressource cible reçoit une requête d’accès, elle vérifie si elle n’a pas préalablement reçu une notification à propos de l’utilisateur concerné et/ou si le contexte d’accès est différent de celui autorisé par les politiques d’accès conditionnel. Le cas échéant, elle rejette la requête d’accès et renvoie l’utilisateur vers AAD avec un challenge pour une réauthentification explicite et une réévaluation des politiques d’accès applicables.
On notera que le CAE n’est pas un mécanisme transparent pour les ressources cibles et que sa mise en œuvre nécessite des modifications dans leur logique de fonctionnement. La mise en œuvre du CAE nécessite une application cliente compatible (CAE-capable client) capable d’interpréter le challenge renvoyé par la ressource cible et de rediriger l’utilisateur vers AAD. Microsoft a pour sa part commencé à implémenter pour les applications de sa suite collaborative M365.
En synthèse
Il est aujourd’hui possible d’implémenter une philosophie Zéro Trust access basée sur l’identité mais pour éviter de tomber dans les travers des modèles de sécurité historiques, il convient de durcir les conditions de délivrance et d’utilisation de ces jetons, sous peine d’en faire les supports d’une confiance implicite et excessive.
L’usage de mécanismes permettant d’intégrer de signaux permettant d’évaluer le contexte de la connexion et d’avoir un contrôle continu sur les jetons délivrés est nécessaire.
Il faut cependant garder en tête que, face au scénario de vol de jetons, ces mécanismes jouent un rôle réactif dépendant des capacités de détection, et non préventif capable d’empêcher l’utilisation de jetons volés. Nous aurons l’occasion de revenir plus en détails dans un prochain article sur la problématique de vol de jetons et sur les différentes solutions existantes et émergentes permettant d’y faire face.