RICOCHET64 VIA GETTY IMAGES

2 failles de sécurité (en cours) avec fuite de données chez pôle emploi

September 16, 2019

Pôle emploi a été averti dès le 16 août de l'existence des 2 failles, avec des démos et la procédure de reproductibilité. Leurs réponses furent catégoriques et expéditives. Histoire.

Depuis 1 an je suis incrit à pôle emploi, dans le cadre de l'ARCE https://www.pole-emploi.fr/candidat/les-aides-financieres-a-la-creation-d-entreprise-@/article.jspz?id=920019, ayant créé la société Please Open It, spécialisée dans les problématiques et les protocoles d'authentification oauth2 et openid connect. Tous les mois, je me connecte donc sur le site de pôle emploi pour effectuer mon actualisation.

Début août 2019, Pôle Emploi déploie un nouveau système d'authentification sur leur site internet. Il faut créer un nouvel identifiant ainsi qu'un mot de passe avec des règles complexes.

J'en avais fait un résumé du ressenti utilisateur et de l'UX : https://twitter.com/mathieupassenau/status/1162350647058059264

En explorant les requêtes transmises, pour savoir pourquoi mon mot de passe était refusé, j'ai constaté un mauvais usage du protocole oauth2 ayant de graves conséquences avec l'envoi des données personnelles du candidat de pôle emploi (Nom, Prénom, Adresse email, identifiant, sexe) vers des serveurs externes à pôle emploi, à savoir ceux de la société AT internet hébergés chez Amazon Web Services.

1. Résumé

Le protocole d'authentification "implicit flow" déconseillé par l'Internet Engineering Task Force (IETF) expose les utilisateurs à un vol de leurs données personnelles et éventuellement de leur session sur le site de pôle emploi. Voir le point 5. L'utilisation du implicit flow

L'utilisation du dit protocole a eu un effet de bord assez gênant. Dans le cadre de la transmission de données normalement anonymisées à des fins statistiques, les données personnelles des candidats (Nom, Prénom, Adresse email, identifiant) sont transmises à des sociétés tierces privées sans aucun chiffrage ni filtre quelqu'il soit, sur des serveurs de la société Amazon. Voir le point 6. Effet de bord : les analytics.

J'ai cherché à contacter le service en charge de la sécurité informatique chez Pôle emploi. La seule réponse du support téléphonique aura été de me rapprocher de mon conseiller pôle emploi, qui aura alerté les services dès le 19 août.
Après de nombreux rappels et la menace de la publication, une personne de la DSI a fini par me contacter. L'objectif était double :

Après un échange téléphonique assez tendu le lundi 10 septembre, les échanges ont lieu par écrit. Tous les éléments exposés dans cet article ont été transmis à pôle emploi dès le début.
Cependant, selon cette personne : "Pour ma part, je pense que, à l’époque où nous avons fait ce choix, c’était le plus pertinent et la position la plus partagée".

C'est donc après un argumentaire léger à propos de choix techniques hasardeux balayants les recommandations de l'IETF "best current practice" ne remettant absolument rien en cause que cette publication a vu le jour afin d'alerter l'ensemble des utilisateurs du site.

2. Authentification web : ne pas utiliser implicit flow

Dans le protocole oauth2, il existe plusieurs moyens d'authentifier un utilisateur sur un client. Le client étant l'application ayant besoin de l'authentification. https://medium.com/@darutk/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85

Pour les applications type "web" ou "mobiles", il faut obligatoirement utiliser des clients du type "publics". Le client sera identifié par un "client_id" qui sera transmis à la demande d'authentification.

L'implicit flow est définit dans la RFC :
https://tools.ietf.org/html/rfc6749#section-4.2

Le principe réside dans la transmission des données d'authentification (appelés "tokens") directement dans l'adresse (URL) et non dans des headers HTTP ou dans le corps d'une requête.

Il s'avère que cette méthode expose les données d'authentification :
https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926

Dans les "best current practice", il est spécifié :
https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13
"The implicit grant (response type "token") and other response types causing the authorization server to issue access tokens in the authorization response are vulnerable to access token leakage and access token replay … In order to avoid these issues, Clients SHOULD NOT use the implicit grant and any other response type causing the authorization server to issue an access token in the authorization response."

En lieu et place d'implicit flow, il faut utiliser authorization_code flow. Cette méthode ajoute une étape supplémentaire. Le code retourné dans l'URL est à usage unique, a une durée de vie très courte et ne contient pas de données personnelles. Grâce à ce code, il est possible de "l'échanger" contre un couple de clés "id_token" et "access_token" qui serviront par la suite aux échanges. Cette opération se fait dans une requête POST à l'URL /token du serveur oauth. Les données sont retournées dans le corps de la requête et non dans l'URL, ce qui les préserve des fichiers de journaux et historiques.

J'ai détaillé cette méthode lors de mon dernier blog post :
https://www.mathieupassenaud.fr/how-oauth2-works-example/

Une excellente explication a été rédigée par Risa Fujii : https://dev.to/risafj/beginner-s-guide-to-oauth-understanding-access-tokens-and-authorization-codes-2988.

3. Les données dans un token JWT

Un "token JWT" est une chaine de caractères, encodée en base64 et signée. Cela permet de faire passer des informations directement dans le jeton d'authentification et non de les demander à chaque fois au serveur. Cependant, encodé et signé ne veut pas dire chiffré. Le token JWT doit contenir le minimum d'informations de l'utilisateur. On préfèrera utiliser des appels d'API pour avoir les détails sur l'utilisateur plutôt que les avoir en permanence dans le token.

Par exemple, un token retourné par Google avec le scope "openid" :

A part le numéro unique d'utilisateur, aucune information n'est stockée dans ce token.

4. Les tokens chez pôle emploi

Dès lors que vous vous authentifiez sur le site de pôle emploi, vous pouvez facilement retrouver le token d'authentification. En faisant une inspection sur la page, on trouve dans la session locale l'access_token (utilisé pour les appels au serveur) et l'id_token, qui contient les informations de l'utilisateur.

Or, ce token a l'air particulièrement bavard :

La récupération de ce token permet donc d'accéder à des informations personnelles, notamment l'adresse email d'un candidat de pôle emploi.

5. L'utilisation du implicit flow

L'application client web de pôle emploi utilise un implicit flow vis-à-vis du serveur d'authentification. Conformément donc au protocole de la RFC, l'id_token et le access_token sont renvoyés dans l'URL, la fameuse "redirect_uri".

En utilisant l'outil d'inspection du navigateur, on retrouve bien la réponse du serveur d'authentification avec l'URL de redirection du navigateur qui contient les informations :

Les informations access_token et id_token sont transmises dans un fragment, c'est à dire après un "#" ce qui va prémunir légèrement de certaines failles d'implicit flow :

Même en utilisant l'option "strip private information" (qui masquera les entêtes, les cookies, le contenu des requêtes), les URL seront sauvegardées dans leur entièreté et donc pourront exposer les id_token et access_token. Cela signifie au minimum récupérer les données personnelles du token jwt, au maximum voler une session en cours si le access_token est toujours valide.

6. Effet de bord : les analytics

Comme beaucoup de sites, le site de pôle emploi fait appel à des solutions d'analytics afin d'avoir des statistiques d'usage et d'utilisation notamment à des fins d'amélioration de la navigation.

En regardant de plus près les requêtes, on constate que 3 sont utilisées :

Les données transmises sont anonymisées. C'est totalement légal et sans aucun danger.

Dans les requêtes transmises, il y a la page depuis par laquelle l'utilisateur est arrivé. Exemple :

Dans certains cas (notamment lors que l'on rafraichi la page), l'authentification est vérifiée auprès du serveur et donc la page de référence devient celle retournée par le serveur de oauth avec implicit flow, donc l'URL contenant access_token (en fragment, c'est à dire à la suite d'un "#").

Pour transmettre une URL en paramètre dans une autre URL, il faut l'encoder avec url_encode. Et donc le "#" séparant le fragment devient "%23" ce qui n'est plus du tout interprêté comme un fragment. Le navigateur envoie donc vers les serveurs de Xiti l'URL de référence contenant un id_token avec toutes les informations personnelles évoquées ci-dessus :

Dans la capture du trafic réseau (après avoir enlevé le https pour "voir" le trafic), on constate bien que le token est transmis par le navigateur :

Ces serveurs de Xiti sont localisés en Irlande chez Amazon :

L'intégralité de ces informations ont déjà été transmises à pôle emploi qui n'a jamais donné de réponse claire.

7. Questions à pôle emploi

Combien de données de demandeurs d'emploi sont parties sur les serveurs d'Amazon par Xiti ?

Qu'avez-vous mis en place sur vos ordinateurs partagés en agence pour vous prémunir des vols de données et de sessions ?

Comptez-vous améliorer l'authentification afin d'être en phase avec les recommandations de la RFC ?

Allez-vous externaliser l'authentification vers les services France Connect ?