Accueil > OpenID Connect OAuth Server par DnC > Développer > OIDC et les Application à page unique : exemple d’une belle mascarade (...)

OIDC et les Application à page unique : exemple d’une belle mascarade ! Incompétence ou mensonge délibéré ?

Une application à page unique (SPA) est une application Web qui charge une seule page HTML à partir du serveur Web, puis la met à jour de manière dynamique en réponse à l’interaction de l’utilisateur et à d’autres événements.

Tirant argument des progrès des navigateurs, permettant à Javascript de mettre en œuvre les règles CORS et d’accéder au cryptage, certains préconisent de mettre en œuvre le flux de code avec autorisation plutôt que le flux implicite.

La magie du flux "Authorization Code" est alors évoquée pour prétendre que l’accès aux données est sécurisé. Ce n’est que pure mascarade ! Bling bling bling ...

Application à page unique

Plusieurs architectures permettent de créer des applications à page unique. La tendance est l’architecture "serveur léger", qui installe sur l’agent utilisateur ( en général le navigateur de l’utilisateur ) la page initiale contenant du code Javascript. Ce code assurera la logique et les transitions d’état de l’application, celle-ci obtenant ses données d’API RESTful protégées par OAuth 2.0. Dans cette configuration, l’application réside sur l’agent utilisateur et non sur le serveur.

Les SPA peuvent (maintenant ?) mettre en œuvre le flux de code avec autorisation (Authorization Code Grant)

Il est de nombreuses configurations dans lesquelles les hôtes de l’application et les points de terminaison des services se situent sur des serveurs différents : serveur d’authentification, ressources protégées (RS) ou API.

Les applications à page unique en sont un bon exemple.

En utilisation Web normale, cette approche multi-hôte ou, plus précisément, "multi-origines" est restreinte pour de bonnes raisons de sécurité. Les déclarations de partage de ressources multi-origines ( Cross-Origin Resource Sharing, CORS ) permettent de contourner la contrainte.

Les navigateurs se sont améliorés depuis la conception du flux implicite. La mise en œuvre de CORS pour autoriser la demande de jeton à partir de JavaScript est maintenant disponible, ainsi que les API de cryptographie nécessaires pour valider la signature du jeton JWT.
Il est donc techniquement possible d’utiliser le flux de code d’autorisation pour l’authentification et l’autorisation des applications sans back-end, y compris pour les applications à page unique.

Faut-il en déduire pour autant que l’utilisation de ce flux, dans cette configuration, garantit la sécurité des données ?

Avec les SPA, les problèmes de la sécurité de l’authentification restent posés

Les SPA sont des applications "sans-back-end". Leur code se trouve sur l’agent utilisateur, donc n’importe où, contrairement aux applications "avec back-end" dont le code est protégé au sein d’un serveur. A ce titre :

- Sont exposés dans le code, de façon plus ou moins accessible au public :
- l’identifiant et le secret de l’application,
- les jetons d’accès ou d’identité.

Avec l’identifiant et le secret, une application malicieuse peut se procurer des jetons. Avec les jetons, elle pourrait demander des données au nom de la véritable application.

- L’URL de redirection est celle de l’application, donc celle de son hôte, c’est à dire l’user-agent. Elle ne peut être inscrite sur le serveur et doit être fournie par l’application.
Si on est dans le cas d’user-agent de stations de travail ( desktops ) situés dans un espace de confiance ( un ou plusieurs domaines connus ), il reste encore possible de comparer cette URL à un modèle enregistré sur le serveur d’autorisation. Mais même dans ce cas, si l’application malveillante se trouve sur le même hôte [1], la distinction est impossible. Si on a affaire à une application de mobile, cela devient vraiment impossible.

- Dans le cas d’une application de mobile, la demande de jeton au point d’entrée Token et la réponse ne circulent pas dans une liaison de serveur ( celui de l’application ) à serveur ( le serveur d’authentification ) dans laquelle les deux extrémités sont identifiées, mais entre différents mobiles non identifiés et le serveur d’authentification. Une des qualités reconnues du flux de code d’autorisation appliqué aux clients avec back-end disparaît.

Dans le cas d’une SPA comme dans celui de toute application sans back-end [2], il n’est pas possible d’identifier avec certitude l’application présentant le jeton comme étant bien celle qui l’a obtenu au cours de la procédure d’authentification.

Encapsuler les données cryptées dans une classe Javascript ???

Avec les SPA, il est possible d’éviter de stocker des informations d’identification selon les méthodes classiques, telles que les jetons d’accès dans les cookies et le stockage de session. Au lieu de cela, on conservera les données sensibles dans des variables JavaScript.

Certains recommandent alors d’utiliser une classe Javascript pour stocker et fournir ces variables. Cette méthode reçoit le joli nom d’"encapsulation" qui donne un aspect sérieux et innovant à une méthode pourtant bien banale.

Cependant, il ne s’agit là que d’une méthode d’obfuscation dont l’efficacité est insuffisante face à un attaquant déterminé. Un simple debugger permet d’exécuter pas à pas le code et de voir passer les variables.

Pourquoi les spécifications confirment-elles une pratique douteuse ?

On peut lire dans le document Health Relationship Trust Profile for OAuth 2.0 :

2.1.3. Client intégré au navigateur avec délégation d’utilisateur

Ce type de client s’applique aux clients qui agissent pour le compte d’un propriétaire de ressource particulier et nécessitent la délégation des droits de cet utilisateur pour accéder à la ressource protégée. De plus, ces clients sont intégrés à un navigateur Web et partagent efficacement une session active entre les systèmes.

Ces clients utilisent le flux implicite de OAuth 2 en envoyant un propriétaire de ressource au noeud final d’autorisation pour obtenir une autorisation. L’utilisateur DOIT s’authentifier auprès du noeud final d’autorisation. Le navigateur Web de l’utilisateur est ensuite redirigé vers un URI hébergé par le client, à partir duquel le client peut directement obtenir un jeton d’accès. Étant donné que le client lui-même ne s’authentifie jamais auprès du serveur et que le jeton est mis directement à la disposition du navigateur, ce flux ne convient que pour les clients incorporés dans un navigateur Web, tel qu’un client JavaScript sans composant de serveur principal. Dans la mesure du possible, il est préférable d’utiliser le flux de code d’autorisation en raison de ses propriétés de sécurité supérieures.

Ce type de client NE DOIT PAS demander ou recevoir un jeton d’actualisation. Les jetons d’accès émis à ce type de client DOIVENT être de courte durée et DEVRAIENT être rejetés à l’expiration de la session authentifiée de l’utilisateur avec le client.

Il est donc bien reconnu qu’il y a un problème que le flux de code d’autorisation ne résoudra pas. Ce flux est sans doute "de sécurité supérieure", mais dans le cas des applications sans back-end il échoue à identifier l’application.

Pourtant, la rédaction du paragraphe donne à penser que le flux de code d’autorisation fera mieux que le flux implicite. Et pas un mot n’est dit sur l’exposition du secret de l’application.

C’est une mascarade : n.f. comédie hypocrite, mise en scène trompeuse.

Un article présentant le contre et optant pour le pour

Voici un article intéressant pour l’analyse qui est faite : SECURELY USING THE OIDC AUTHORIZATION CODE FLOW AND A PUBLIC CLIENT WITH SINGLE PAGE APPLICATIONS.

L’auteur préconise l’utilisation du flux d’autorisation avec code pour les SPA publiques, mais en fait une analyse détaillée qui ( contrairement au titre et à la conclusion de l’article, voilà encore une ambigüité ) met bien en évidence les multiples insuffisances de la configuration.

En titrant sur les applications publiques, l’auteur évite au moins la divulgation du secret de l’application, puisqu’il n’y en a pas. Cela va faciliter le travail des applications malicieuses ! n’allons pas demander des données protégées comme cela ...

Il existe des informations complémentaires, connectez vous pour les voir.

Notes

[1ce qui est non seulement le cas courant mais aussi le cas ( worst case ) que l’on doit prendre en compte pour une analyse de sécurité

[2Tout comme dans le cas d’une application native de mobile et de toute application sans back-end. C’est le même problème, sauf peut-être les applications mobiles de desktop dans un espace de confiance