web-dev-qa-db-fra.com

Pourquoi les jetons de rafraîchissement sont-ils considérés comme non sécurisés pour un SPA?

Je lisais la documentation sur le site Auth0 concernant Refresh Tokens and SPA , et ils déclarent que les SPA ne devraient pas utiliser Refresh Tokens car ils ne peuvent pas être stockés en toute sécurité dans un navigateur, et utilisez plutôt l'authentification silencieuse pour récupérer de nouveaux jetons d'accès.

Une application de page unique (implémentant normalement la subvention implicite) ne doit en aucun cas obtenir un jeton d'actualisation. La raison en est la sensibilité de cette information. Vous pouvez le considérer comme des informations d'identification d'utilisateur, car un jeton d'actualisation permet à un utilisateur de rester authentifié essentiellement pour toujours. Par conséquent, vous ne pouvez pas avoir ces informations dans un navigateur, elles doivent être stockées en toute sécurité.

Je suis confus. D'après ma compréhension, la seule façon de récupérer un nouveau jeton d'accès serait de soumettre une nouvelle demande au serveur Auth, avec une certaine forme de cookie de session Auth0 pour authentifier l'utilisateur qui est connecté. Lors de la réception du cookie de session, l'Auth0 le serveur serait alors en mesure d'émettre un nouveau jeton d'accès.

Mais en quoi est-ce différent de la présence d'un jeton d'actualisation dans le navigateur ou dans le stockage local? Qu'est-ce qui rend le cookie de session plus sûr qu'un jeton d'actualisation? Pourquoi l'utilisation d'un jeton d'actualisation dans un SPA est-elle une mauvaise chose?

11
Eric B.

Les jetons d'actualisation ne sont pas utilisés dans les SPA, car pour l'utiliser - et pour obtenir un nouveau jeton d'accès à partir du /token, le SPA doit avoir un secret client, qui ne peut pas être stocké en toute sécurité dans un navigateur. Mais puisque le OAuth 2.0 pour Native Apps RFC recommande de ne pas exiger de secret client pour le /token endpoint (pour les clients publics), les jetons d'actualisation peuvent être utilisés même dans les SPA.

Pour obtenir un jeton d'actualisation, vous devez utiliser Auth code grant , qui transmet le code dans une URL de redirection, qui va au serveur hébergeant le SPA (qui peut être un point d'attaque supplémentaire). L'octroi implicite fournit des jetons uniquement à un navigateur (une partie de hachage de l'URL de redirection ne parvient pas au serveur).

La différence entre l'utilisation d'un jeton d'actualisation et d'un cookie de session SSO - le cookie est probablement plus sécurisé, car il peut être marqué comme HttpOnly , ce qui le rend inaccessible aux attaques utilisant du code JavaScript.

3
Ján Halaša

Bonne question - Il n'y a donc pas de moyen vraiment sûr de stocker des jetons sur un navigateur (ou toute autre information confidentielle) - voir liens tels comme ceci . Par conséquent, les applications de page unique (SPA) ne doivent pas stocker de jeton d'actualisation - un jeton d'actualisation est particulièrement problématique, car il a une longue durée de vie (longue expiration ou pas d'expiration), et s'il est volé, un attaquant peut continuer à actualiser les jetons d'accès après chaque expiration individuelle .

Il serait préférable de simplement récupérer votre jeton d'accès lorsque vous en avez besoin (par exemple pour appeler une API) et de stocker uniquement en mémoire (toujours vulnérable à XSS/CSRF) mais mieux - ou d'utiliser et d'oublier. Ensuite, effectuez un autre appel checkSession la prochaine fois que vous aurez besoin d'un jeton d'accès.

Pour votre question - la demande checkSession ne nécessite pas l'envoi d'un Token. C'est littéralement comme son nom l'indique - une "session de vérification" par rapport au serveur d'autorisation pour voir si une session existe. Si c'est le cas, la réponse du serveur d'autorisation inclura un nouveau jeton d'accès. Voir ici pour un exemple d'utilisation avec SPA

N'hésitez pas à me laisser des commentaires sous cette réponse si quelque chose nécessite plus de précisions, etc.

3
arcseldon

Il y a beaucoup de malentendus sur les cookies et les jetons d'actualisation et OAuth2.

Premièrement, il n'est pas vrai que seuls les clients confidentiels peuvent utiliser un jeton d'actualisation. Le protocole OAuth2 indique que les clients confidentiels doivent s'authentifier, mais ne nécessite pas de clients confidentiels. Ergo, l'authentification client est facultative sur l'opération de rafraîchissement. Voir RFC 6749, Section 6, Actualisation d'un jeton d'accès .

Deuxièmement, vous devez comprendre quelles sont les alternatives:

  1. Forcer l'utilisateur à entrer son nom d'utilisateur et son mot de passe toutes les 5 minutes (à chaque expiration du jeton d'accès)
  2. Jetons d'accès longue durée
  3. Authentification via les cookies HTTP

Tout le monde dans le monde, qui n'utilise pas de jetons d'actualisation, utilise l'option # 3. L'authentification via les cookies est 100% fonctionnelle et sécurisée équivalente au stockage d'un jeton d'actualisation. Bien sûr, avec les jetons et les cookies, il existe des options pour les conserver:

une. HTTP uniquement, b. sécurisé (nécessite TLS/SSL) et c. session (en mémoire) vs persistante (local, stockage de domaine)

L'option "HTTP uniquement" s'applique uniquement aux cookies et, par conséquent, peut représenter le seul avantage de l'utilisation de cookies par rapport aux jetons. C'est à dire. les jetons sont gérés via Javascript, il n'y a donc pas d'option pour les garder à l'écart des scripts. Cela dit, les jetons ne sont disponibles que pour Javascript depuis le domaine de la page qui les a stockés (ou comme autorisé par la politique CORS). Donc, ce problème peut être exagéré.

Bien sûr, il faut faire attention à toujours utiliser TLS/SSL pour transmettre des cookies d'authentification ou des jetons. Honnêtement, puisque nous savons que la plupart des violations se produisent au sein du réseau privé d'entreprise, TLS de bout en bout est désormais une exigence de base.

Enfin, que les cookies ou les jetons soient toujours persistants, c'est-à-dire stockés quelque part qui survivent à la fermeture du navigateur ou même au redémarrage de l'appareil, cela dépend du compromis que vous faites entre convivialité et sécurité - pour votre application.

Pour les applications qui nécessitent un niveau de sécurité supérieur, il suffit de tout garder en mémoire (c'est-à-dire les cookies de session, les jetons dans une variable Javascript). Mais pour les applications qui ne nécessitent pas autant de sécurité et qui veulent vraiment une durée de vie de session de plusieurs jours ou semaines, vous devez les stocker. Quoi qu'il en soit, ce stockage n'est accessible qu'aux pages et scripts du domaine d'origine et, par conséquent, les cookies et les jetons sont fonctionnellement équivalents.

3
Charlie Reitzel