Sitecore s’oriente vers une architecture composable avec un modèle de développement principalement sans tête, où toute la logique métier est déplacée vers une application principale, qui devient également un point d’intégration majeur, dont la majorité nécessite une sorte d’authentification.
TL;DR Ne travaillez pas avec un token d’authentification sur un client ! Mais que se passe-t-il si j’en ai besoin ? Ensuite, lisez le reste de cet article de blog pour comprendre quels sont vos risques et vos options.
Dans l’article, nous examinerons les raisons de la nécessité de travailler avec le jeton sur le client de l’application Web et découvrirons ce qui convient le mieux pour stocker le jeton : localStorage, sessionStorage ou cookie sans le HttpOnly
drapeau (la réponse: aucun d’eux!). Nous examinons également les mesures à utiliser pour réduire le risque de fuites de jetons à travers diverses vulnérabilités.
Introduction
Les façons de faire correctement l’authentification et l’autorisation sont l’un des sujets les plus populaires dans le développement Web. Il existe diverses bonnes, mauvaises et mauvaises pratiques que je rencontre encore dans la vie de tous les jours lorsque je fouille certains sites Web avec des outils de développement. Avec cet article, nous allons en parler. Je veux prêter attention au problème, expliquer sa signification et également conseiller les approches pour améliorer la sécurité lors de l’utilisation de jetons sur le client.
Le problème
Une implémentation d’authentification défectueuse lors de l’utilisation de jetons sur un client augmente la vulnérabilité. Le scénario courant : avoir un jeton d’accès pour certaines ressources exposées côté client, suivi d’une attaque XSS, donne aux voleurs le même accès aux mêmes données que les scripts légitimes auraient.
On dirait :
… nous travaillons avec
%framework%
ou%library%
où tous les problèmes doivent être pris en compte. Pourquoi m’en soucierais-je ?
Cela semble raisonnable, n’est-ce pas ? Cependant, la réalité n’est pas si simple et, dans la plupart des cas, il est presque impossible de garantir la sécurité. Il peut y avoir des situations où les menaces de sécurité proviennent d’endroits complètement différents. Imaginez, placer le jeton dans un cookie générique non HttpOnly et sécuriser l’application de XSS à l’absolu, n’empêche toujours pas une violation, simplement parce que l’un des sous-domaines détient un projet vulnérable qui néglige toutes ces mesures de sécurité.
Mais pourquoi un jeton d’accès volé est-il dangereux ? Avec lui, les attaquants pourront faire des demandes aux ressources API en notre nom ou simplement usurper l’identité de notre compte dans leur navigateur, obtenant le même niveau d’accès.
Cas maléfique n°1 : jeton d’accès dans localStorage
L’application reçoit un jeton d’accès du backend et l’enregistre dans le stockage local. Dans ce cas, s’il y a une vulnérabilité XSS, le jeton peut être obtenu par un attaquant. Disons que le jeton a une durée de vie de 15 minutes. Y a-t-il un risque que des attaquants utilisent le jeton en moins de 15 minutes ? Absolument! À mon avis, le risque est trop grand pour que cette approche soit envisagée.
Evil Case #2 : une paire de jetons d’accès et d’actualisation dans localStorage
Un cas avancé de l’exemple précédent. Un jeton d’accès a la même durée de vie, mais il existe également un jeton d’actualisation longue durée, une chaîne utilisée pour obtenir un nouveau jeton d’accès actualisé. Alors qu’un jeton d’accès est utilisé pour accéder à une ressource protégée, un jeton d’actualisation vous permet de demander un nouveau (ou supplémentaire) jeton d’accès. Comme dans l’exemple ci-dessus, un attaquant XSS peut accéder à la fois à un jeton d’accès et à un jeton d’actualisation de très longue durée.
Il existe un ensemble de mesures pour améliorer la sécurité des jetons d’actualisation : rotation des jetons, protection contre la réutilisation, bon (raisonnablement équilibré) sélection de la durée de vie, et autres. Cependant, ces mesures devraient compléter et ajouter plutôt que remplacer la protection contre les fuites de jetons XSS.
Cas maléfique n° 3 : jeton d’accès dans un cookie générique non HttpOnly
J’ai rencontré cette approche plusieurs fois et elle porte le plus grands risques de tous ceux ci-dessus. Je crois que l’intention d’utiliser un cookie générique est censée être pour une authentification « transparente » entre les sous-domaines, mais je voudrais mettre en garde contre l’utilisation négligente d’une telle approche.
Le hic, c’est que le jeton placé dans un cookie devient disponible pour tous les sous-domaines d’un site donné. Même si un attaquant ne parvient pas à trouver un trou XSS dans l’application principale, un service vulnérable peut exister parmi les nombreux sous-domaines. En fait, la numérisation des sous-domaines est une technique typique utilisée dans les tests d’intrusion. les sous-domaines peuvent contenir beaucoup de choses sales : un ancien site, un projet de test, un bac à sable/terrain de jeu, des API non protégées ou tout service similaire potentiellement vulnérable. En plus de cela, il peut également y avoir une attaque de prise de contrôle de sous-domaine qui permet également à un attaquant de voler le jeton de la même manière.
Pourquoi du tout alors on a besoin de travailler avec un jeton sur un client ?
La question logique venant de ce qui précède est : pourquoi avons-nous besoin de rendre le jeton disponible sur un client et de travailler avec lui ? Pourquoi ne pas simplement le mettre dans un cookie renforcé par session ? Outre la mauvaise conception de l’application, je pourrais citer quelques raisons valables.
1. Utiliser des jetons sans état
Contrairement aux jetons « avec état » qui servent de clé aux données de session conservées sur un serveur, ce jeton est autosuffisant et contient toutes les informations requises pour l’autorisation. En règle générale, les jetons JWT sont utilisés à cette fin et ils ont une structure standard :
En raison du bloc de signature JWT, la validité pourrait être vérifiée lors de la réception d’une demande ayant un tel jeton (soit une clé privée pour le chiffrement symétrique, soit une clé publique pour le chiffrement asymétrique). Cela signifie que la validation JWT a lieu sans le serveur émetteur (c’est à dire. pas besoin d’accéder à une base de données pour chaque validation).
L’approche permet d’éviter de stocker des jetons sur un serveur en émettant un tel jeton JWT lors de l’authentification et en le conservant chez un client.
2. Utilisation d’OAuth 2.0/OIDC pour l’authentification dans votre propre application
Une chose assez populaire consiste à utiliser, par exemple, le flux d’octroi de code d’autorisation dans OAuth2.0 ou OpenID Connect (OIDC).
Certains confondent OpenID Connect avec OAuth 2.0 – en fait, OIDC étend OAuth 2.0 et est un protocole d’authentification, tandis qu’OAuth 2.0 est nativement un protocole d’autorisation. Cependant, vous pouvez souvent voir des implémentations d’OIDC en plus d’OAuth 2.0. La différence est que dans le cas du serveur d’autorisation OIDC, le serveur de ressources joue également un rôle, mais uniquement pour l’identité de l’utilisateur.
3. Utilisation de SPA sans backend
Sans s’appuyer sur un backend, les développeurs sont obligés de rechercher des moyens de travailler avec le jeton sur le client. Les litiges sur Internet étaient autrefois populaires là où il est préférable de stocker un jeton pour travailler avec : dans localStorage, sessionStorage ou cookies (bien sûr, sans HttpOnly
). En fait, en termes de sécurité, il n’y a pratiquement aucune différence. Et c’est pourquoi:
Source link