mission-apprentissage / referentiel

GNU Affero General Public License v3.0
3 stars 1 forks source link

Trous de sécurité dans la gestion des tokens d'authentification #217

Open ldaverio opened 2 weeks ago

ldaverio commented 2 weeks ago

L'application "référentiel" autorise un mode d'authentification par des tokens JWT [Wikipédia]. Les URL d'authentification sont construites sur le modèle :

https://referentiel.apprentissage.onisep.fr/login?token={valeur-du-token}

La valeur d'un token (chaîne de caractères) est divisée en 3 parties :

  1. un en-tête (décrivant l'algorithme de chiffrement utilisé)
  2. une charge utile composés de champs plus ou moins normalisés (exemple ci-dessous)
  3. une signature numérique (qui certifie l'intégrité des données de la "charge utile")

L'en-tête et la charge utile figurent "en clair" (encodage Base64) dans le token, et leur intégrité est normalement vérifiée par la signature numérique du token.

Or, il semble que l'application ne décode pas les tokens de manière sécurisée :

  1. Lors du décodage, elle ne tient pas compte de la date d'expiration inscrite dans le token (le champ exp de la charge utile). Les tokens générés actuellement semblent être expirés. Ce qui signifie qu'une fois qu'un accès est donné via un token, il est donné "à vie" (à moins de changer le "secret" stocké sur le serveur, ce qui invalide tous les tokens).

  2. Plus grave, le décodage du token ne tient pas compte de la signature, ce qui signifie qu'il est possible / facile pour une personne malveillante de générer un token arbitraire (invalide) "à la main", et donc de s'authentifier avec n'importe quel rôle. Cela me semble être un trou de sécurité significatif.

Exemple d'en-tête :

{"typ": "jwt", "alg": "HS512"}

Exemple de charge utile :

{'code': '00',
 'type': 'academie',
 'nom': 'Étranger',
 'iat': 1662387277,
 'exp': 1693944877,
 'iss': 'referentiel',
 'sub': '00'}

Le champ exp contient la date d'expiration du token, ici le 5/9/2023 à 22h14m37s.

FlavieSauvebois commented 2 weeks ago

Bonjour Laurent, Merci pour tes investigations. Effectivement ce système de token n'est pas satisfaisant en terme de sécurité et de traçabilité des modifications sur l'application. C'est pourquoi nous allons prochainement lancer un nouveau système d'identification via des comptes utilisateurs personnalisés. C'est Yohan qui a travaillé et développé un module spécifique. On pourra te parler de tout ça jeudi.

ldaverio commented 2 weeks ago

Un rapide survol du code concerné (fichier server/src/http/middlewares/authMiddleware.js) semble indiquer en effet que le nouveau mécanisme sera différent. Je ne suis pas sûr d'avoir compris s'il utilisera des cookies ou des tokens JWT. Les tokens seraient plus indiqués pour une application moderne (frontend/backend) a priori. Mais l'essentiel est que ça fonctionne de façon sécurisée :)

ldaverio commented 1 week ago

Je vais m'occuper de corriger le problème