La plupart des applications web manipulent des données personnelles et/ou des données business ; autant dire des données sensibles. Mots de passe, adresses email, numéros de cartes bancaires, données santé et autres, sont au centre de la bataille qui oppose deux camps. D’un côté les entreprises, de petite, moyenne ou grande taille, qui cherchent à se défendre contre des intrusions dans leurs systèmes d’information. Et de l’autre, des assaillants de plus en plus expérimentés, attirés par l’appât du gain et stimulés par les nombreuses brèches trop souvent ignorées par leurs futures victimes.
Les applications web, cibles principales des cyberattaques
Étant exposées au public, les applications web ont naturellement une surface d’attaque étendue et éventuellement des fonctionnalités avec un grand nombre d’éléments variés potentiellement vulnérables. Même sur un serveur Web sécurisé s’exécutant sur un système d’exploitation réputé sûr, des failles de sécurité peuvent subsister car elles sont la plupart du temps dues à des fautes de programmation de l’application elle-même ou des erreurs du configuration du serveur l’hébergeant.
Dans ce premier billet, d’une série d’articles consacrée aux failles les plus courantes rencontrées lors de nos tests d’intrusion, nous nous focaliserons sur les vulnérabilités de la couche applicative des plateformes web. Nous reviendrons plus en détail sur la sécurité des serveurs et des APIs dans nos prochains articles.
Par ailleurs, cet article n’est pas un jugement à charge, dans le sens où nous avons conscience des contraintes auxquelles font face de nombreuses équipes de développement, CTO ou RSSI : budget, disponibilité, organisation, etc. Il n’est pas non plus à décharge, car les attaques réussissent très souvent, en raison de négligences qui pourraient être facilement évitées. L’objectif de cet article est de montrer en quoi il est important de porter une attention « sécurité » particulière, dès la phase de conception, tout au long du développement et du cycle de vie de vos applications web pour se prémunir contre des attaques de plus en plus nombreuses et sophistiquées.
Mettre en place des mesures de sécurité adaptées à vos enjeux, sensibiliser ou former vos équipes, réaliser des tests d’intrusion sont autant de leviers disponibles pour renforcer votre sécurité et parer les éventuelles attaques que nous présentons dans cet article.
Quelles sont les vulnérabilités courantes des applications web et comment se protéger ?
Fonction authentification et attaques par force brute
Bien évidemment, une application web peut être attaquée de front. Cibler la fonction d’authentification est l’attaque la plus directe et évidente. L’attaque la plus courante contre les systèmes d’authentification est l’attaque par force brute. Dans ce cas de figure, un attaquant, via l’utilisation d’outils spécifiques, bombarde une page d’authentification avec des valeurs d’identifiant et de mots de passe jusqu’à ce qu’il obtienne un accès à une application web.
Ce type d’attaque est facilité si le message d’erreur de l’échec de l’authentification donne l’origine de l’erreur. Ainsi « l’utilisateur n’existe pas » permet à l’attaquant de ne pas tenter d’entrer des mots de passe pour cet utilisateur absent de la base de compte. « Mot de passe incorrect » permet à l’attaquant de se concentrer sur cet utilisateur, ce qui lui fait gagner beaucoup de temps.
Il existe de nombreuses variantes d’attaques par force brute. Le « password spraying », qui consiste à tester un ensemble limité de mots de passe sur plusieurs comptes, en est une. En effet, dans ce cas de figure, les attaquants tentent d’accéder à une plateforme en testant un petit nombre de mots de passe couramment utilisés, et ce sur un grand nombre de comptes. Ils partent du principe qu’au sein d’un grand groupe de personnes, il est probable qu’il y en ait au moins une qui utilise un mot de passe commun, et c’est malheureusement trop souvent le cas.
Cette approche plus lente leur permet de tenter d’accéder à plusieurs comptes sans être bloqués, ce qui pourrait alerter la cible de l’attaque. Un exemple concret d’attaque par « password spraying » que nous avons réalisé dans le cadre d’un test d’intrusion en boite noire sur une application SaaS :
- Extraction des profils LinkedIn de l’entreprise
- Création des emails à partir du nom, prénom et du pattern [email protected]
- Password spraying sur le backoffice en utilisant une petite liste de mots de passe : Entreprise, entreprise, entreprise2021, Entreprise2021, entreprise2021! et Entreprise2021!
- Obtention d’un compte administrateur avec accès au backoffice
- Extraction de la liste de tous les utilisateurs avec accès au backoffice
- A nouveau password spraying, qui a permis d’obtenir d’autres comptes
Les attaques par force brute sont redoutables et ne sont pas à prendre à la légère. Il est conseillé de mettre en place des mesures techniques anti « brute force », comme :
- Sécuriser le mécanisme de login en limitant le nombre de connexions non valides et en augmentant le délai après et entre chaque tentative de login.
- Mettre en place un système d’authentification multi-facteurs (au moins deux), afin de s’assurer que le processus de login est bien réalisé par une personne et non un bot. Il peut s’agir d’une réponse à une question secrète, le renseignement d’un code reçu par SMS, ou de répondre à un test Captcha.
D’autres mesures simples (politique de mots de passe forts, messages d’erreur génériques, consultation régulière des journaux de logs, etc.), une sensibilisation continue et des formations sur la sécurité web, sont de bons moyens de se prémunir contre ce type d’attaque.
Gestion des droits d’accès et élévation de privilèges
Les utilisateurs d’une application sont censés être dignes de confiance et respecter les politiques de sécurité en place. Mais le sont-ils toujours ? Des utilisateurs légitimes ont de nombreuses raisons potentielles de devenir « malveillant » à certains moments :
- Pour éviter une procédure qu’ils ne comprennent pas et qu’ils peuvent contourner, en utilisant une fonctionnalité à laquelle ils ne sont pas supposés avoir accès
- Pour avoir accès aux données d’un autre utilisateur pour des raisons diverses
- Pour accéder à des fonctionnalités réservées à un groupe d’utilisateurs, comme par exemple utiliser gratuitement des services payants
La gestion des droits d’accès est un élément central dans la sécurité des applications web. C’est sûrement l’aspect le plus ciblé par des attaquants malveillants, souhaitant « élever leurs privilèges » pour parvenir à leurs fins. On parle en effet d’élévation de privilèges lorsqu’un utilisateur exploite une faille, un défaut de conception ou une erreur de configuration dans une application pour obtenir un accès élevé à des ressources qui devraient normalement lui être inaccessibles. Il peut alors utiliser les privilèges nouvellement acquis pour voler des données confidentielles, exécuter des commandes administratives ou déployer des logiciels malveillants ; et potentiellement causer de graves dommages à votre système d’information et votre image de marque.
Généralement, les attaquants commencent par exploiter une vulnérabilité au niveau des droits d’accès dans un système ou une application cible, ce qui leur permet de passer outre les limitations du compte utilisateur actuel. Ils peuvent ensuite accéder aux fonctionnalités et aux données d’un autre utilisateur. Puis leur objectif consistera à obtenir des privilèges élevés, généralement ceux d’un administrateur (le Graal !) ou d’un autre utilisateur puissant.
Un exemple concret que nous avons réalisé dans le cadre d’un test d’intrusion en boite grise sur une application SaaS :
- Accès à un compte utilisateur standard dans l’environnement de production, avec des actions limitées au sein du back-office : consultation de documents, envoi de demandes de divers types via système de workflows, etc.
- Grâce à un bug dans le back-office lié aux paramètres d’URLs, il a été possible d’accéder à des fonctionnalités disponibles à l’équipe support uniquement, ayant notamment la possibilité de mettre à jour les adresses email de tous les autres utilisateurs de la solution (dont les personnes disposant de droits super admin sur le back-office)
- Ces fonctionnalités de l’équipe support nouvellement acquises, il a été possible de modifier l’email d’un super admin et de réinitialiser le mot de passe via la notification email reçu en ce sens
Heureusement, cette vulnérabilité critique a été découverte dans le cadre d’un test d’intrusion. Nul besoin de préciser en quoi les conséquences auraient été désastreuses pour l’entreprise si jamais une attaque de ce type était survenue.
Les applications constituent le point d’entrée le plus facile pour toute attaque, il est donc vital de les sécuriser : implémenter les meilleures pratiques de développement pour éviter les erreurs de programmation et de configuration, utiliser des scanners de vulnérabilité pour vérifier si vos applications sont faillibles, et réaliser des tests d’intrusion pour assurer que les niveaux de droits implémentés sont bien segmentés et cloisonnés.
Exploitation de failles XSS
Supposons que la porte du back-office d’une application web soit solide, et son enceinte protégée par des remparts impénétrables. Les attaquants « irréductibles » se tourneront alors vers le front-office pour essayer d’injecter du contenu malveillant dans l’application via n’importe quel champ ou système d’envoi de données disponible.
Le Cross Site Scripting (abrégé XSS) est une vulnérabilité courante des applications web qui, bien exploitée, peut permettre de voler une session, remplacer une partie de l’interface utilisateur, télécharger des logiciels malveillants [etc.] via de l’injection de code (JavaScript, HTML, CSS). Il existe 2 types d’attaques XSS :
- Les attaques XSS stockées (stored XSS attacks) qui envoient un contenu malicieux sur le serveur hébergeant une application web, afin qu’il soit renvoyé dans le navigateur des utilisateurs.
- Les attaques XSS reflétées (reflected XSS attacks) qui ne stockent pas le contenu malicieux sur le serveur web, mais qui le livrent aux utilisateurs de l’application via une URL ou directement sur le navigateur.
En somme, les attaques XSS reposent sur l’envoi de contenus malicieux affichés sur le navigateur des utilisateurs d’une application web, sous forme de pop-up ou une redirection vers un site externe.
Il est difficile de détailler toutes les conséquences possibles des attaques XSS, la liste serait très longue. Pour s’en protéger, il faut partir du principe que les données reçues par une application web ne peuvent pas être considérées comme « toujours » sûres. Il est important de suivre des règles strictes pour traiter les données venant de l’extérieur. Tout contenu doit être nettoyé, validé et/ou encodé avant d’être utilisé par l’application. Les scanners de vulnérabilités peuvent repérer certaines de ces vulnérabilités, mais un test d’intrusion ou une revue de code seront plus complets.
Les attaques par injection SQL
Les attaques par injection sont facilitées par le fonctionnement même des applications web, car elles ont besoin de données pour fonctionner. Et plus il faut de données, plus les opportunités d’attaques par injection sont nombreuses.
Une vulnérabilité courante : les failles d’injection SQL ; qui permettent d’interagir avec la base de données d’une application par le biais de requêtes non-prévues. Ces failles peuvent conduire à des vols, pertes de données, une suppression ou une manipulation des données stockées.
Sécurité des systèmes interconnectés
Les applications web sont souvent reliées à des services ou systèmes tiers, notamment pour faire communiquer des données. La plupart des FinTech utilisent par exemple des systèmes de paiement, développés et commercialisés par des tiers, pour les intégrer à leurs applications web maison. Ces systèmes de paiement sont généralement sécurisés car il existe de nombreux standards en matière de sécurité dans le domaine du paiement électronique, notamment PCI-DSS.
Vous l’aurez compris, une application tierce peut être robuste sur le plan de la sécurité, mais des vulnérabilités apparaissent très souvent en raison d’un problème de configuration et/ou d’implémentation du système d’interconnexion (web services, APIs : nous reviendrons plus en détail sur les failles courantes et les bonnes pratiques de sécurité des APIs dans notre prochain article).
Sécurité des composants tiers
Les composants tiers sont un des points d’attraction favoris des attaquants car la plupart des applications web en contiennent. Utiliser des librairies ou des frameworks est une pratique courante. Cela permet de développer plus rapidement et plus facilement des applications, et ce, en tirant parti de l’appui d’une communauté active. Cependant, ces composants tiers sont exposés à des attaques web. Et pour ne pas arranger les choses, plus un composant est populaire, plus il est l’objet d’attaques. En effet, lorsqu’une faille de sécurité est découverte sur un composant, elle devient souvent publique.
La solution : un patch est développé afin de corriger cette faille dans la nouvelle version, qui sera « normalement » installée par les développeurs utilisant ces composants tiers. Le problème : les attaquants attendent également les mises à jour contenant les détails des vulnérabilités découvertes, afin de lancer rapidement des attaques sur des composants critiques.
Les possibilités de failles sont, comme sur toute autre application, nombreuses (injections, XSS, failles d’authentification, etc.). Un exemple rencontré dans le cadre d’un test d’intrusion en boite grise sur une application SaaS permettant la gestion de données financières d’entreprises :
- Plateforme fermée du point de vue d’un attaquant externe, seul un formulaire d’authentification était accessible
- Après des tests approfondis et des recherches poussées en direction des composants tiers utilisés, nous avons repéré une librairie javaScript
- La version installée étant ancienne, elle présentait une vulnérabilité connue qui permettait notamment de lire n’importe quel fichier présent sur le serveur l’hébergeant
- En l’exploitant, il a été possible d’extraire de nombreux fichiers sensibles présents sur le serveur web, et d’accéder in fine à l’intégralité des données gérées par la plateforme web.
Pour contrer ces attaques, nous conseillons de limiter au maximum l’utilisation de composants tiers, si vous disposez des ressources permettant de s’en passer. Vous aurez toujours plus la main sur la sécurité d’un développement-maison que d’un composant externe.
Si cela n’est pas possible, il est important de maintenir à jour une liste des composants tiers utilisés sur votre application web, et leurs versions. Cela facilitera l’identification des composants vulnérables, et votre l’équipe de développement pourra agir si besoin, en ayant une connaissance précise des éléments utilisés. Pour ce faire, il est conseillé d’assurer une veille technique et technologique afin de surveiller les nouvelles versions disponibles et les vulnérabilités découvertes sur les composants tiers utilisés. S’inscrire à des mailing lists projets (celles des composants utilisés), ou des mailings lists de sécurité sont autant de moyens de rester informé et sur le qui-vive.
Au-delà des failles techniques, des failles logiques souvent oubliées
Les vulnérabilités techniques sont inhérentes aux applications web. Au-delà de ces vulnérabilités, il subsiste aussi des failles logiques qui, elles sont liées aux workflows, et indétectables avec des outils automatiques (scanners et autres). Qu’est-ce qu’une faille logique ?
Une faille logique existe lorsque le fonctionnement normal d’une application, autrement dit une étape logique ou un processus prévu, peut être évité ou contourné.
Un exemple concret de faille logique découverte dans le cadre d’un test d’intrusion en boite noire sur une plateforme e-commerce :
- Création d’un compte pour effectuer des achats sur la plateforme
- Ajout de produits dans le panier puis passage à l’étape de validation du panier
- Modification du prix des produits ajoutés au panier (sans changer leurs références) en éditant directement le code HTML, ce qui a entrainé une baisse de la valeur « affichée » de notre panier
- Enfin, il a été possible de valider le paiement de notre panier (à tarif réduit), car le prix indiqué dans la requête de paiement envoyée à la banque prenait comme référence le prix du panier affiché dans notre navigateur.
Ceci a été possible car la plateforme n’effectuait pas de vérification et se fiait aux entrées utilisateur. Afin de se prémunir, il est préférable que le serveur indique le prix à payer à la banque en fonction de la référence des produits voulus. L’affichage du prix coté utilisateur ne doit être qu’une indication visuelle pour lui-même et non une valeur à prendre en compte.
En somme, les failles logiques sont généralement le résultat d’un défaut de conception des applications web ou d’un manque de tests approfondis d’un point de vue sécurité. Et si tests sécurité il y a, il est nécessaire de se focaliser sur ce que l’application n’est pas supposée permettre pour détecter ses faiblesses logiques.
Pour ce faire, il est nécessaire de bien comprendre le comportement attendu de l’application, la logique et les règles métiers, les contrôles sécurité qui en découlent, et donc les potentiels abus fonctionnels, puis de faire preuve de créativité pour construire des scénarios imprévus, et enfin les tester sur l’application.
Réaliser des tests d’intrusion d’application web pour évaluer et réduire les risques sécurité
Les tests d’intrusion d’application web sont la solution par excellence pour faire face aux attaques informatiques. Ne dit-on pas que la meilleure défense, c’est l’attaque ! Cet adage résume parfaitement le principe des tests d’intrusion, qui consistent en effet à tester la sécurité d’une application ou d’un autre système en réalisant diverses attaques afin d’identifier des vulnérabilités techniques et logiques potentielles.
Lors d’un test d’intrusion d’application web, trois approches sont possibles : des tests en boite noire, des tests en boite grise ou des tests en boite blanche. Ces approches correspondent à différents niveaux d’information et d’accès fournis aux pentesters. Les tests d’intrusion en boite noire ciblent la surface d’attaque accessible à n’importe quel attaquant externe, tandis que des tests d’intrusion en boite grise vont concerner des éléments disponibles avec des accès fournis par le Client (et non accessibles autrement). Un test d’intrusion en boite blanche quant à lui permet d’analyser le niveau de sécurité en disposant de tout ou partie du code source de l’application et d’un accès à l’infrastructure l’hébergeant.
Les tests d’intrusion d’application web permettent de rechercher des vulnérabilités liées à la configuration des serveurs web ainsi que des vulnérabilités liées à la couche applicative. Côté serveur, il s’agit par exemple de services ouverts et mal sécurisés, de logiciels non à jour, ou d’erreurs de configuration. Et nous reviendrons sur ce point dans notre prochain article. Côté applicatif, il s’agit des vulnérabilités répertoriées par l’OWASP (les failles du top 10 dont certaines ont été abordées plus haut), ainsi que les failles logiques.
Un rapport complet est remis suite à un test d’intrusion. Ce livrable inclut la méthodologie employée, les vulnérabilités identifiées (classifiées par niveau de criticité : faible, importante, critique), l’exploitation possible ainsi que des recommandations de correction. Une présentation des résultats de l’audit, par le(s) pentester(s) en charge de l’audit permet d’échanger sur les résultats de l’audit de sécurité.
Chez Vaadata, nous démocratisons les tests d’intrusion avec des offres adaptées aux startups comme aux grandes entreprises. Il est tout autant possible de réaliser un premier test d’intrusion d’une journée à 675 euros (incluant rapport et présentation des résultats), que de partir sur un audit plus en profondeur avec un budget compris entre 2500 et 10 000 euros (tarif déterminé en fonction de la complexité fonctionnelle et technique et votre application web, ainsi que du niveau de profondeur souhaité).
Contactez-nous pour toute question relative à un projet de tests d’intrusion sur votre application web. Nous échangerons sur vos besoins et vous proposerons une intervention adaptée à vos enjeux sécurité et vos contraintes, qu’elles soient budgétaires ou organisationnelles.