Nous réalisons des pentests tous les jours. (Enfin, 5 jours sur 7). Aujourd’hui, nous vous faisons passer en coulisse : nous avons regardé de plus près les tests d’intrusion menés en 2020, afin de partager avec vous quelques chiffres sur les failles trouvées.
Nous avons également relevé les trois vulnérabilités qui reviennent le plus fréquemment durant nos pentests et donnons notre éclairage sur la présence de ces failles. Enfin, nous présentons quelques autres observations issues de nos pentests.
Statistiques sur les pentests réalisés par Vaadata
Spécialisés en pentest, nous réalisons des pentests d’applications web, applications mobile, réseaux internes d’entreprises, objets connectés et ingénierie sociale. Les statistiques suivantes reflètent uniquement notre activité et ne sont qu’un éclairage d’un environnement cybersécurité bien plus large. Cet article sur les statistiques cybersécurité 2021 donne par exemple un point de vue plus global.
Concernant notre typologie de clients, près de 50% sont des startups (de early stage jusqu’à série C ou plus). Un tiers sont des sociétés éditrices de logiciels de taille moyenne ou intermédiaire, et le reste se répartit entre des grand-comptes et des PME de différents secteurs. Notre point de vue porte donc principalement sur la sécurité des startups, par rapport au point de vue d’autres entreprises de pentest.
Nous avons conduit près de 200 pentests durant l’année 2020, et 40% des projets sont menés pour des clients existants.
Nous avons constaté que :
- 29% des cibles avaient au moins une faille critique,
- 44% avaient une ou plusieurs failles importantes,
- 47% avaient une ou plusieurs failles medium,
- 62% avaient des failles medium ou importantes ou critiques.
En moyenne, nous avons trouvé au cours d’un pentest :
- 0,7 faille critique,
- 1,3 failles importantes,
- 1,3 failles medium,
- 2,6 failles faibles,
- 0,7 faille de niveau information.
Il est difficile de comparer les résultats des 200 pentests, car le périmètre et le niveau de profondeur des tests sont différents pour chaque situation. Certains pentests « rapides » où peu de failles ont été remontées auraient pu avoir des résultats différents en élargissant le périmètre ou en rajoutant du temps pour approfondir les recherches.
Divers éléments sont à prendre en compte pour situer la maturité en sécurité de la cible des tests (technologies utilisées, culture sécurité de l’entreprise, process, compétences individuelles au sein de l’équipe…).
D’un point de vue plus global, sur l’ensemble des failles trouvées,
- 11% étaient des failles critiques,
- 19% des failles importantes,
- 20% des failles medium,
- 40% des failles faibles,
- 10% des failles de niveau information.
Les risques d’une faille de sécurité sont estimés en prenant en compte la probabilité d’exploitation de la faille et de son impact potentiel. Les enjeux sécurité sont déterminants et pris en compte pour établir la criticité d’une vulnérabilité. Donner une évaluation claire du niveau de criticité facilite la priorisation des corrections.
20% des pentests ont été suivis d’une phase de vérification. Cette phase permet d’achever le pentest en vérifiant que toutes les failles ont été corrigées, mais aussi que les correctifs sont efficaces et n’ont pas créé de nouveaux problèmes de sécurité via des effets de bord.
Les trois vulnérabilités les plus fréquemment trouvées lors d’un pentest web
Nous réalisons des pentests sur des cibles très variées, que ce soit par rapport au contexte fonctionnel, au métier ou au type de pentest mené.
Nous conduisons en majorité des pentests web, car ces cibles ont un niveau d’exposition aux risques élevé. Ce sont des pans souvent vulnérables des systèmes d’information et leur surface d’attaque est de plus potentiellement étendue.
Sur ces pentests web, nous avons noté que les trois failles rencontrées le plus fréquemment sont :
- les Cross Site Scripting (XSS),
- les problèmes de droits (cloisonnement des données entre utilisateurs, élévation de privilèges),
- le manque de rate limiting.
Savoir quelles sont les failles les plus courantes permet de vérifier et consolider les éléments sources de vulnérabilité. Le but de cet article est de les mettre en lumière et de vous inciter à faire particulièrement attention à ces éléments, afin de limiter les risques.
Les failles les plus fréquemment trouvées : Cross Site Scripting (XSS)
Ces failles sont connues et étudiées depuis les années 2000. Mais elles sont encore trouvées fréquemment et ne donnent pas signe d’une disparition prochaine. L’impact de cette attaque peut être important. L’exploitation d’une XSS peut servir à compromettre le contenu d’une page pour récupérer des informations sensibles, à voler des tokens de session, etc.
Plus que le choix du langage ou de la technologie utilisée, nous avons constaté que la présence de failles XSS dépend principalement de la façon dont les solutions sont implémentées. Plusieurs facteurs expliquent que ces failles soient encore présentes :
- Nous avons observé un manque de sensibilisation. Tous les développeurs ne sont pas forcément formés aux risques liés aux XSS et l’impact de ces vulnérabilités n’est parfois pas perçu correctement.
- Nous avons noté un manque d’utilisation de frameworks. Les frameworks intègrent et gèrent beaucoup d’éléments de sécurité. Lorsqu’un site ou une application est codé sans framework, il est malheureusement facile d’écrire du code vulnérable aux XSS et de faire des oublis dans les vérifications et contrôles des données reçues.
Les frameworks ne sont pas encore utilisés dans toutes les situations. Il faut avoir appris à les utiliser et cela vient dans un deuxième temps lorsque les développeurs apprennent à coder. Il arrive ainsi parfois que des entreprises ont développé leurs solutions sans framework au départ, selon les compétences présentes dans les équipes. Lorsque ces entreprises grandissent, il devient difficile de tout changer pour utiliser un framework.
- Nous avons aussi eu des situations où des frameworks sont utilisés, mais modifiés par les équipes de développement, ce qui a provoqué des failles. Les frameworks ont des protections intégrées, mais il est possible manuellement de désactiver la protection. Par exemple avec Symfony, vous pouvez activer le html pour que les balises soient interprétées, mais cela crée des risques. Il faut alors bien nettoyer ce qui va être affiché.
Se protéger des failles Cross Site Scripting (XSS)
Pour contrer ces failles, nous recommandons d’encoder les données utilisateurs en sortie. Toute entrée utilisateur doit être encodée en HTML lorsqu’elle est réutilisée dans la page web d’une application. Par exemple, les caractères < et > seront respectivement remplacées par les entités HTML correspondantes, soit < et >.
De manière optionnelle, vous pouvez également filtrer et valider les données à l’arrivée. Il s’agit de traiter les données envoyées par les utilisateurs avant de les accepter. Par exemple, dans un formulaire, il est possible de mettre des filtres pour que le code postal soit uniquement cinq chiffres.
Cette solution ne doit cependant pas être utilisée seule, car cela revient à appliquer un filtre par liste noire, et il est facile d’oublier d’inclure certains éléments dangereux.
Pour approfondir sur la protection du Cross Site Scripting, l’OWASP met à disposition une très bonne cheat sheet qui détaille différents encodages.
Les failles XSS sont identifiables par les équipes techniques lors de relecture de code manuelle ou par des outils automatiques.
Les failles les plus fréquemment trouvées : les problèmes de droits
Les problèmes de droits couvrent les vulnérabilités liées aux contrôles d’accès. Les contrôles d’accès vérifient si l’utilisateur est autorisé à effectuer l’action appelée ou à accéder aux données demandées. Il y a de multiples endroits où les contrôles d’accès sont implémentés et les workflows sont parfois subtils, c’est pourquoi c’est une faille que nous trouvons très fréquemment.
Les problèmes de droits ne dépendent pas de la complexité de la solution (multiples niveaux de droits, profils variés modulables à la carte…) ni du fonctionnel métier. Nous avons constaté qu’il y a plutôt un manque de sensibilisation à ces failles. Il est souvent oublié que lors des échanges entre le client et le serveur, les requêtes sont faciles à manipuler. Il est possible par exemple de changer un identifiant, de réutiliser un cookie à un endroit non prévu, etc. s’il n’y a pas de contrôles adaptés.
Nous avons observé que les failles de problèmes de droits sont le plus souvent liées à des contrôles insuffisants ou même à une absence de contrôles, et non pas à une mauvaise implémentation des contrôles. Lorsqu’il y a des contrôles d’autorisation en place, ils sont généralement correctement mis en place.
Se protéger des problèmes de droits
Cette vulnérabilité se produit lorsque des contrôles peuvent être manipulés, contournés ou sont insuffisants, afin d’atteindre de nouvelles fonctionnalités ou d’autres données.
Il y a en effet deux types de problèmes de contrôles d’accès aux données :
- verticaux : dans un système où il y a différents niveaux de droits (utilisateur, manager, admin), l’attaquant tente d’obtenir les droits les plus élevés possibles, car cela donne accès à plus de fonctionnalités. En fonction du métier, il peut s’agir de créer ou supprimer des utilisateurs, valider des flux financiers, accéder à des données confidentielles…
- horizontaux : dans une application où il y a différents comptes utilisateurs, l’attaquant essaye d’atteindre les données ou ressources des autres utilisateurs.
Pour se protéger de ces vulnérabilités, l’un des principes est de considérer que les accès et ressources ne sont pas autorisés par défaut. Des contrôles doivent ensuite être mis en place pour vérifier si l’utilisateur a le droit de faire telle action à tel moment. Le contrôle final doit toujours être effectué côté serveur, indépendamment de la présence d’un contrôle côté front.
Vous pouvez choisir différentes méthodes de contrôles des accès : d’après les rôles, d’après l’organisation, d’après des attributs… L’OWASP a une cheat sheet détaillant les avantages et inconvénients de ces différentes méthodes de contrôles d’accès.
Pour identifier ces failles, les équipes de développement peuvent rejouer les requêtes, par exemple avec Postman. Il est important de tester et auditer en profondeur les contrôles mis en place, afin de vérifier qu’ils fonctionnent comme souhaité.
Les failles les plus fréquemment trouvées : le manque de rate limiting
Le manque de rate limiting est une vulnérabilité que nous rencontrons très fréquemment. Elle est de niveau faible ou information et se trouve principalement sur des APIs et sur certaines fonctionnalités, comme le login, la réinitialisation de mot de passe…
Notre piste d’explication pour cette faille est que comme l’impact est modéré, elle est parfois négligée. De plus, les limites peuvent être mises à différents endroits et de différentes manières, cela peut sembler beaucoup d’efforts pour une telle vulnérabilité.
Cette faille nécessite de mettre des limites au niveau de l’hébergement ou dans l’application, afin d’alléger la charge et de protéger les endpoints.
Mettre en place du rate limiting
Le rate limiting, comme son nom l’indique, limite le nombre d’exécutions d’une opération. Il sert à se protéger des usages excessifs pour garder la disponibilité du service et éviter l’abus de certaines fonctions (par exemple, les fonctions d’envoi d’emails).
Le manque de rate limiting peut provoquer des dénis de services ou un ralentissement de l’exécution de l’opération voulue, mais également permettre les attaques par brute force.
Pour se protéger, nous vous conseillons de mettre en place un rate limiting global. Il s’agit de fixer un nombre de requêtes maximal possibles par IP.
Il est également possible de combiner un rate limiting par IP et par utilisateur.
Observations issues des pentests réalisés par Vaadata
Nous avons aussi pu tirer de notre expérience quelques observations plus générales. Tout d’abord, il n’y a pas de langages où les failles seraient plus fréquentes parce qu’il s’agit d’un langage en particulier. Il est possible d’avoir une solution sécurisée avec tout langage informatique, l’important est de choisir un langage adapté à votre besoin.
Ensuite, le niveau sécurité ne dépend pas de la fonctionnalité de la cible. Un site où l’on peut mettre uniquement des commentaires peut être sécurisé, tandis qu’un autre avec un panneau administrateur ne le sera pas. Le niveau de sécurité d’une solution découle bien plus de l’investissement de l’entreprise dans la sécurité, s’il s’agit d’une priorité et que des moyens ont été alloués pour les équipes.
Lorsque les process de l’entreprise et l’organisation des projets incluent la sécurité, il est ainsi possible de transférer les connaissances sécurités acquises lors d’un pentest à des cibles non testées. Les recommandations suite à un pentest sont alors appliquées aux nouveaux développements, sur d’autres actifs de l’organisation, etc. C’est ainsi que l’entreprise pourra renforcer son niveau de sécurité global et devenir mature en sécurité.
Enfin, nous avons remarqué que la sécurité des réseaux internes est souvent moins renforcée que la sécurité d’application web par exemple. En effet, le réseau interne est encore considéré comme un élément moins à risque du système d’information, car moins exposé. De plus, les technologies réseau sont plus anciennes : elles ont été conçues en ayant peu la sécurité comme priorité et peuvent être moins faciles à sécuriser au premier abord.
Mais la généralisation de l’IoT et la multiplication des ransomwares font que la situation est en train de changer. Les risques sur l’infrastructure augmentent actuellement et un réseau sécurisé devient essentiel pour garantir la bonne conduite de l’activité d’une entreprise. Heureusement, il est totalement possible d’avoir une infrastructure sécurisée en suivant les préconisations actuelles.