< Back
Common client-side vulnerabilities of web applications

Tags:

TCS BELUX TCS BELUX newsletter Risk and threat evaluation
06 May 2025

Vulnérabilités courantes côté client des applications web

Vous connaissez peut-être le Top 10 de l’OWASP, qui fait généralement reference à la liste des 10 principaux risques de sécurité des applications web de l’OWASP. Mais il est moins connu que l’OWASP a publié plusieurs de ces Top 10, comme celui pour les API ou celui pour les applications mobiles. Dans le même esprit, ils ont publié une proposition pour un "Top 10 des risques de sécurité côté client" en 2022, axée sur le front-end des applications web, qui peut être comparée à celle des applications mobiles car elles traitent toutes deux de la sécurité côté client.

Cette liste n'est pas définitive et est encore en cours de construction, mais elle est intéressante car elle met en lumière certains des éléments les plus importants à considérer pour les développeurs front-end afin d'éviter les erreurs de sécurité.

Dans cette newsletter, nous passerons en revue les 10 éléments de la liste pour les expliquer et proposer des solutions afin d'éviter les problèmes associés. Comme nous le verrons, certains d'entre eux ne sont pas si faciles à comprendre, et certains nécessitent même une certaine interprétation.

Contrôle d'accès côté client défaillant

"Contrôle insuffisant de l'accès JavaScript aux ressources côté client (données et code), exfiltration de données sensibles ou manipulation du DOM à des fins malveillantes (pour accéder à ces ressources)."

Cette première vulnérabilité est courante dans les applications qui reposent fortement sur JavaScript ou tout autre traitement côté client (comme WASM). Parfois, le client envoie une requête à une API juste après l'authentification pour obtenir les droits associés à l'utilisateur. Si la réponse du serveur a été altérée, par exemple avec Burp Suite, le client affichera plus de fonctionnalités que prévu initialement. Selon l'implémentation, les fonctionnalités qui ne devraient pas être visibles seront ou ne seront pas fonctionnelles ; si le back-end effectue des vérifications de contrôle d'accès sur les requêtes reçues, les fonctionnalités ne fonctionneront pas. Cependant, il arrive que le back-end se repose trop sur le front-end et fasse confiance à toutes ses requêtes.

Pour éviter ce problème, la meilleure solution est de ne pas gérer les autorisations dans le front-end. Le back-end doit être responsable de la vérification des autorisations et répondre uniquement avec les fonctionnalités autorisées pour l'utilisateur. Le JavaScript ne doit pas être responsable de déterminer si une fonctionnalité doit être disponible pour un utilisateur ou non. De plus, toutes les requêtes doivent être vérifiées pour le contrôle d'accès afin d'éviter celles fabriquées par l'utilisateur.

XSS basé sur le DOM

"Vulnérabilités permettant des attaques XSS par manipulation ou abus du DOM."

Ce type de XSS (Cross-Site Scripting) est le résultat de la modification du HTML d'une page par JavaScript à la volée en fonction des entrées de l'utilisateur. C'est de là que vient la partie DOM (qui signifie Document Oriented Model).

L'idée est d'abuser du JavaScript qui modifie une page en fonction de différents types d'entrées contrôlables par l'utilisateur, telles que les balises URL, les entrées de formulaire… Ces entrées sont appelées "sources" et voici les plus ciblées :

▪️ document.URL

▪️ document.documentURI

▪️ location.href

▪️ location.search

▪️ location.*

▪️ window.name

▪️ document.referrer

L'exécution du code se produit lorsque l'entrée provenant de l'une des sources mentionnées est transmise à un "sink", où l'entrée de l'utilisateur est écrite. Les sinks les plus populaires pour le XSS basé sur le DOM sont les suivants :

▪️ document.write

▪️ (element).innerHTML

▪️ Eval

▪️ setTimeout

▪️ setInterval

▪️ execScript

Pour éviter ce problème, le JavaScript devrait utiliser ce qu'on appelle un "safe sink". L'idée est d'utiliser la propriété “textContent” du placeholder au lieu du HTML lui-même. De plus, les données provenant d'une source ne devraient jamais être transmises à une fonction JavaScript qui exécute du code, comme "eval" ou "setTimeout".

Une nouvelle protection qui a été proposée contre ces vulnérabilités est les "Trusted Types". Ils fonctionnent de manière similaire aux instructions préparées SQL. Une implémentation de ce mécanisme a été publiée par le W3C. Cette solution pourrait devenir la solution par défaut contre les vulnérabilités du DOM si son développement continue.

En guise de note complémentaire sur ce point de la liste, il convient de noter que le XSS basé sur le DOM n'est pas le seul type de vulnérabilité du DOM, prenons par exemple la vulnérabilité de redirection ouverte basée sur le DOM.

Fuite de donnés sensibles

"Incapacité à détecter/prévenir les traceurs numériques et les pixels sur une propriété web afin de garantir le respect des lois nationales et internationales sur la confidentialité"

La capacité à garantir une gestion appropriée et un contrôle total des données recueillies auprès d'un client est désormais exigée par la loi dans de nombreux pays/régions (RGPD par exemple). Cette tâche est complexifiée par l'utilisation des nombreux composants nécessaires au bon fonctionnement des applications modernes. La détection et/ou la prévention des traceurs numériques est donc une exigence pour toutes les applications souhaitant opérer dans ces parties du monde. Cependant, elle est souvent négligée car très difficile à mettre en œuvre.

La manière la plus efficace de garantir le contrôle des données utilisateur est d'analyser en profondeur le besoin commercial d'une fonctionnalité en termes de données afin de s'assurer de ne recueillir que le minimum nécessaire. Le même aspect s'applique au suivi du comportement des utilisateurs. Une analyse stricte des données requises doit être effectuée pour s'assurer de ne collecter que les données nécessaires pour fournir les métriques attendues.

Composants vulnérables et obsolètes

"Absence de détection et de mises à jour des bibliothèques JavaScript obsolètes ou contenant des vulnérabilités connues.”

C'est l'une des vulnérabilités côté client les plus rencontrées. Les composants peuvent être difficiles à maintenir à jour, principalement en raison de contraintes de temps.

C'est peut-être lié à de nombreux facteurs, tels que des changements incompatibles ou une méconnaissance des vulnérabilités. Il arrive également que les développeurs ne soient pas conscients que le composant est utilisé (le composant est apporté par un autre).

Le meilleur example de ce problème est JQuery. Beaucoup de ses anciennes versions ont des vulnérabilités connues, parfois avec des exploits publics. Dans deux évaluations de vulnérabilité des applications web sur trois, l'application utilise une version vulnérable de JQuery.

L'objectif n'est pas de blâmer les développeurs de JQuery ni les développeurs utilisant JQuery, c'est un excellent outil. Mais il est important de savoir que l'utilisation de composants externes implique de les maintenir à jour pour éviter d'être exposé à leurs vulnérabilités. Des outils comme Retire.js peuvent aider à identifier les composants utilisés qui ont des vulnérabilités connues.

Absence de contrôle de l'origine des tiers

"Le contrôle de l'origine permet de restreindre certains actifs ou ressources web en comparant l'origine de la ressource à l'origine de la bibliothèque tierce. Sans utiliser de tels contrôles, le risque de la chaîne d'approvisionnement augmente en raison de l'inclusion de code tiers inconnu ou non contrôlé qui a accès aux données de l'origine du site.”

CORS, ou Cross Origin Resource Sharing, devrait être utilisé pour s'assurer que le JavaScript ou le code chargé de manière externe ne requête jamais des points de terminaison API auxquels il ne devrait pas accéder. L'objectif est d'éviter que du code non contrôlé accède à des données sensibles.

Les CORS sont un mécanisme côté front-end activé avec l'en-tête "Access-Control-Allow-Origin" dans la réponse du serveur.

Dérive JaveScript

"Incapacité à détecter les changements au niveau des actifs et du code JavaScript utilisé côté client. Cela inclut l'incapacité à détecter les changements de comportement de ce code pour déterminer si les changements sont potentiellement malveillants. Cela est particulièrement important pour les bibliothèques tierces.”

Lorsque l'application récupère des composants tiers directement auprès du fournisseur, il est possible qu'un bug ou un comportement malveillant soit ajouté lors d'une mise à jour.

La manière la plus simple de prévenir ce problème est de vérifier une somme de contrôle de la ressource importée pour s'assurer qu'aucun changement non vérifié n'a été effectué. Cependant, ce processus est risqué car il nécessite que le mainteneur de l'application vérifie et adapte l'application très rapidement après chaque mise à jour des composants tiers.

Une autre option est d'imposer l'utilisation d'une version spécifique du composant, ce qui permet aux développeurs de revoir les nouvelles versions avant de les utiliser. Il est préférable d'imposer des versions spécifiques plutôt que d'utiliser des exigences permissives telles que "Version = 1.*" ou "Version >= 1.0" pour s'assurer que chaque version peut être revue avant d'être utilisée.

La fonctionnalité de sécurité du navigateur Content-Security-Policy et Subresource Integrity peut également être utilisée pour prévenir les comportements indésirables.

Données sensibles stockées côté client

"Stockage de données sensibles telles que les mots de passe, les secrets cryptographiques, les jetons API ou les données personnelles identifiables (PII) dans un stockage persistant côté client comme le LocalStorage, le cache du navigateur, ou un stockage transitoire comme les variables JavaScript dans une couche de données.”

Ce problème est courant sur les clients lourds mais est également présent sur les clients web. Comme détaillé dans la description de l'OWASP, certaines applications stockent des informations critiques côté client telles que des mots de passe, des clés cryptographiques, etc. L'emplacement du secret côté client peut varier. Il peut se trouver dans les différents stockages du navigateur, les commentaires du code, les variables JavaScript, etc.

Parfois, ce problème est une omission, et le secret n'a pas besoin d'être accessible par le côté client. Pour éviter cela, il est important d'inclure des scripts dans votre processus CI/CD pour vérifier qu'aucun secret n'est présent dans la version publiée du produit.

Dans les cas où le secret est volontairement utilisé par le front-end, c'est simplement une erreur de conception et le traitement nécessitant le secret devrait être effectué par le back-end.

Avec l'essor de WASM, il est important de noter que les mêmes restrictions doivent être appliquées. Inspecter le code et la mémoire d'une application WASM à la recherche de secrets n'est pas si difficile.

Echec de logging et de surveillance de la sécurité côté client

"Surveillance et détection insuffisantes des changements côté client et des accès aux données, en particulier des échecs et des erreurs, en temps réel à mesure que chaque page est assemblée et exécutée en utilisant à la fois du code propriétaire et du code tiers.”

Il peut être important de suivre ce qui se passe côté client de l'application car cela peut permettre de détecter des bugs ou des attaques. Celles-ci peuvent être dues à une mise à jour d'un composant tiers ou à des actions de l'utilisateur. La journalisation de ces erreurs dans le back-end peut être utile pour agir rapidement afin d'éviter tout type de dommages. Ce type de journalisation peut également aider à prévenir les attaques, si l'attaquant ne bloque pas les requêtes de journalisation, car le test des charges utiles entraîne souvent des erreurs.

Le reporting de la Content-Security-Policy est un bon début pour journaliser le chargement de ressources inattendues et l'exécution de code, et pour les prévenir.

Ne pas utiliser les contrôles de sécurité standard des navigateurs

"Ne pas utiliser les contrôles de sécurité basés sur des normes courantes intégrées dans les navigateurs tels que les sandboxes d'iframe, les en-têtes de sécurité comme la Content Security Policy (CSP), l'intégrité des sous-ressources, et de nombreuses autres fonctionnalités de sécurité standard.”

De nos jours, les navigateurs intègrent de nombreuses fonctionnalités de sécurité empêchant l'application de charger du contenu provenant de ressources indésirables, d'exécuter du code indésirable ou d'imposer le chiffrement TLS. Ces fonctionnalités sont un excellent moyen d'améliorer facilement la sécurité d'une application, surtout lorsqu'une autre mesure de sécurité échoue.

Cependant, elles peuvent parfois être difficiles à configurer correctement (comme la Content-Security-Policy par exemple), c'est pourquoi elles sont trop souvent laissées de côté ou mal configurées par les développeurs pour leur faciliter la tâche.

Cela peut être acceptable dans un environnement de test ou de développement, mais lorsqu'elles sont mises en production, ces fonctionnalités doivent être ajoutées et correctement configurées pour maximiser la robustesse de l'application contre diverses attaques telles que le XSS.

Inclure des informations propriétaires côté client

"Présence de logique métier sensible, de commentaires de développeurs, d'algorithmes propriétaires ou d'informations système contenues dans le code côté client ou les données stockées.”

Ce point est très lié au premier point de cette liste : du point de vue de la sécurité, tous les traitements critiques d'une application doivent être effectués par le back-end et non par le front-end. Toute action effectuée et/ou donnée stockée sur le front-end peut être considérée comme publique (ou du moins non secrète).

Tous les traitements sensibles ou propriétaires doivent être effectués par le back-end. Lorsqu'ils sont mis en production, le front-end de l'application doit être dépouillé de ses commentaires.

Conclusion

Bien que cette liste ne soit pas définitive et que certains points soient redondants, elle propose des lignes directrices intéressantes sur ce qu'il faut vérifier lors de la création d'un front-end d'application web.

Authors

Elliot Rasch

Alexis Pain