10 vulnérabilités de sécurité Web les plus courantes
Publié: 2022-03-11Pour trop d'entreprises, ce n'est qu'après qu'une faille de sécurité s'est produite que les meilleures pratiques de sécurité Web deviennent une priorité. Au cours de mes années de travail en tant que professionnel de la sécurité informatique, j'ai vu à maintes reprises à quel point le monde des problèmes de sécurité du développement Web peut être obscur pour tant de mes collègues programmeurs.
Une approche efficace des menaces de sécurité Web doit, par définition, être proactive et défensive. À cette fin, ce message vise à susciter un état d'esprit de sécurité, en injectant, espérons-le, au lecteur une bonne dose de paranoïa.
En particulier, ce guide se concentre sur 10 pièges de sécurité Web courants et importants à connaître, y compris des recommandations sur la manière de les atténuer. L'accent est mis sur les 10 principales vulnérabilités Web identifiées par l'Open Web Application Security Project (OWASP), une organisation internationale à but non lucratif dont l'objectif est d'améliorer la sécurité des logiciels dans le monde entier.
Un peu d'introduction à la cybersécurité avant de commencer - authentification et autorisation
Lorsque je parle avec d'autres programmeurs et professionnels de l'informatique, je rencontre souvent une confusion concernant la distinction entre autorisation et authentification. Et bien sûr, le fait que l'abréviation auth soit souvent utilisée pour les deux contribue à aggraver cette confusion courante. Cette confusion est si courante que ce problème devrait peut-être être inclus dans cet article sous le nom de "Common Web Vulnerability Zero".
Alors avant de continuer, clarifions la distinction entre ces deux termes :
- Authentification : Vérification qu'une personne est (ou du moins semble être) un utilisateur spécifique, puisqu'elle a correctement fourni ses identifiants de sécurité (mot de passe, réponses aux questions de sécurité, scan d'empreintes digitales, etc.).
- Autorisation : confirmation qu'un utilisateur particulier a accès à une ressource spécifique ou est autorisé à effectuer une action particulière.
En d'autres termes, l' authentification consiste à savoir qui est une entité, tandis que l' autorisation consiste à savoir ce qu'une entité donnée peut faire. Dans cet esprit, passons aux 10 principaux problèmes de sécurité Internet.
Erreur courante de sécurité Web #1 : failles d'injection
Les failles d'injection résultent d'un échec classique pour filtrer les entrées non fiables. Cela peut arriver lorsque vous transmettez des données non filtrées au serveur SQL (injection SQL), au navigateur (XSS - nous en reparlerons plus tard), au serveur LDAP (injection LDAP) ou n'importe où ailleurs. Le problème ici est que l'attaquant peut injecter des commandes à ces entités, entraînant la perte de données et le piratage des navigateurs des clients.
Tout ce que votre application reçoit de sources non fiables doit être filtré, de préférence selon une liste blanche. Vous ne devriez presque jamais utiliser une liste noire, car il est très difficile d'y parvenir et généralement facile à contourner. Les produits logiciels antivirus fournissent généralement des exemples stellaires de listes noires défaillantes. La correspondance de modèle ne fonctionne pas.
Prévention : La bonne nouvelle est que la protection contre l'injection consiste « simplement » à filtrer correctement votre entrée et à déterminer si une entrée est fiable. Mais la mauvaise nouvelle est que toutes les entrées doivent être correctement filtrées, à moins qu'elles ne soient incontestablement fiables (mais le dicton "ne jamais dire jamais" me vient à l'esprit ici).
Dans un système avec 1 000 entrées, par exemple, filtrer avec succès 999 d'entre elles n'est pas suffisant, car cela laisse encore un champ qui peut servir de remède d'Achille pour faire tomber votre système. Et vous pourriez penser que mettre un résultat de requête SQL dans une autre requête est une bonne idée, car la base de données est fiable, mais si le périmètre ne l'est pas, l'entrée provient indirectement de personnes malveillantes. C'est ce qu'on appelle l'injection SQL de second ordre au cas où vous seriez intéressé.
Étant donné que le filtrage est assez difficile à faire correctement (comme la cryptographie), ce que je conseille généralement est de s'appuyer sur les fonctions de filtrage de votre framework : elles ont fait leurs preuves et sont minutieusement examinées. Si vous n'utilisez pas de frameworks, vous devez vraiment réfléchir sérieusement à la pertinence de ne pas les utiliser dans le contexte de sécurité de votre serveur. 99% du temps non.
Erreur courante de sécurité Web #2 : authentification cassée
Il s'agit d'un ensemble de problèmes multiples pouvant survenir lors d'une authentification interrompue, mais ils ne proviennent pas tous de la même cause première.
En supposant que quelqu'un veuille encore lancer son propre code d'authentification en 2014 (à quoi pensez-vous ??), je le déconseille. Il est extrêmement difficile de bien faire les choses, et il existe une myriade de pièges possibles, pour n'en citer que quelques-uns :
- L'URL peut contenir l'identifiant de session et le divulguer dans l'en-tête du référent à quelqu'un d'autre.
- Les mots de passe peuvent ne pas être chiffrés ni en stockage ni en transit.
- Les identifiants de session peuvent être prévisibles, donc l'accès est trivial.
- La fixation de session pourrait être possible.
- Le détournement de session peut être possible, les délais d'attente ne sont pas correctement implémentés ou utilisent HTTP (pas de sécurité SSL), etc…
Prévention : le moyen le plus simple d'éviter cette vulnérabilité de sécurité Web consiste à utiliser un framework. Vous pourrez peut-être l'implémenter correctement, mais le premier est beaucoup plus facile. Au cas où vous voudriez rouler votre propre code, soyez extrêmement paranoïaque et renseignez-vous sur les pièges. Il y en a plusieurs.
Erreur courante de sécurité Web #3 : Cross Site Scripting (XSS)
Il s'agit d'un échec de nettoyage des entrées assez répandu (essentiellement un cas particulier d'erreur courante n° 1). Un attaquant donne à votre application Web des balises JavaScript en entrée. Lorsque cette entrée est renvoyée à l'utilisateur non nettoyée, le navigateur de l'utilisateur l'exécute. Cela peut être aussi simple que de créer un lien et de persuader un utilisateur de cliquer dessus, ou cela peut être quelque chose de beaucoup plus sinistre. Lors du chargement de la page, le script s'exécute et, par exemple, peut être utilisé pour envoyer vos cookies à l'attaquant.
Prévention : Il existe une solution de sécurité Web simple : ne pas renvoyer les balises HTML au client. Cela a l'avantage supplémentaire de se défendre contre l'injection HTML, une attaque similaire par laquelle l'attaquant injecte du contenu HTML brut (tel que des images ou des lecteurs flash invisibles et bruyants) - pas à fort impact mais sûrement ennuyeux (« s'il vous plaît, faites que ça s'arrête ! »). Généralement, la solution de contournement consiste simplement à convertir toutes les entités HTML, de sorte que <script>
est renvoyé sous la forme <script>
. L'autre méthode de nettoyage souvent utilisée consiste à utiliser des expressions régulières pour supprimer les balises HTML à l'aide d'expressions régulières sur <
et >
, mais cela est dangereux car de nombreux navigateurs interpréteront très bien le code HTML gravement endommagé. Mieux vaut convertir tous les personnages en leurs homologues échappés.
Erreur courante de sécurité Web n° 4 : références d'objets directes non sécurisées
Il s'agit d'un cas classique de confiance dans les entrées des utilisateurs et de payer le prix d'une vulnérabilité de sécurité qui en résulte. Une référence d'objet directe signifie qu'un objet interne tel qu'un fichier ou une clé de base de données est exposé à l'utilisateur. Le problème avec cela est que l'attaquant peut fournir cette référence et, si l'autorisation n'est pas appliquée (ou est cassée), l'attaquant peut accéder ou faire des choses dont il devrait être exclu.
Par exemple, le code a un module download.php
qui lit et permet à l'utilisateur de télécharger des fichiers, en utilisant un paramètre CGI pour spécifier le nom du fichier (par exemple, download.php?file=something.txt
). Soit par erreur, soit par paresse, le développeur a omis l'autorisation du code. L'attaquant peut désormais l'utiliser pour télécharger tous les fichiers système auxquels l'utilisateur exécutant PHP a accès, comme le code de l'application lui-même ou d'autres données laissées sur le serveur, comme des sauvegardes. Oh-oh.
Un autre exemple de vulnérabilité courant est une fonction de réinitialisation de mot de passe qui s'appuie sur la saisie de l'utilisateur pour déterminer le mot de passe à réinitialiser. Après avoir cliqué sur l'URL valide, un attaquant peut simplement modifier le champ du nom d' username
dans l'URL pour dire quelque chose comme "admin".
Soit dit en passant, ces deux exemples sont des choses que j'ai moi-même vues apparaître souvent "dans la nature".
Prévention : Effectuez l'autorisation de l'utilisateur correctement et de manière cohérente, et ajoutez les choix à la liste blanche. Le plus souvent, cependant, tout le problème peut être évité en stockant les données en interne et en ne s'appuyant pas sur leur transmission par le client via des paramètres CGI. Les variables de session dans la plupart des frameworks sont bien adaptées à cette fin.
Erreur courante de sécurité Web n° 5 : mauvaise configuration de la sécurité
D'après mon expérience, les serveurs Web et les applications qui ont été mal configurés sont beaucoup plus courants que ceux qui ont été configurés correctement. Peut-être parce qu'il ne manque pas de moyens de bousiller. Quelques exemples:
- Exécution de l'application avec le débogage activé en production.
- Avoir la liste des répertoires activée sur le serveur, ce qui laisse fuir des informations précieuses.
- Exécution de logiciels obsolètes (pensez aux plugins WordPress, à l'ancien PhpMyAdmin).
- Avoir des services inutiles en cours d'exécution sur la machine.
- Ne pas modifier les clés et mots de passe par défaut. (Ça arrive bien plus souvent que vous ne le pensez !)
- Révéler les informations de gestion des erreurs aux attaquants, telles que les traces de pile.
Prévention : Ayez un bon processus (de préférence automatisé) de « construction et déploiement », qui peut exécuter des tests lors du déploiement. La solution de mauvaise configuration de sécurité du pauvre est les hooks post-commit, pour empêcher le code de sortir avec des mots de passe par défaut et/ou des éléments de développement intégrés.

Erreur courante de sécurité Web n° 6 : exposition des données sensibles
Cette vulnérabilité de sécurité Web concerne la crypto et la protection des ressources. Les données sensibles doivent être chiffrées à tout moment, y compris en transit et au repos. Aucune exception. Les informations de carte de crédit et les mots de passe des utilisateurs ne doivent jamais voyager ou être stockés en clair, et les mots de passe doivent toujours être hachés. Évidemment, l'algorithme de crypto/hachage ne doit pas être faible - en cas de doute, les normes de sécurité Web recommandent AES (256 bits et plus) et RSA (2048 bits et plus).
Et s'il va sans dire que les identifiants de session et les données sensibles ne doivent pas voyager dans les URL et que les cookies sensibles doivent avoir l'indicateur de sécurité activé, cela est très important et ne peut être surestimé.
La prévention:
En transit : utilisez HTTPS avec un certificat approprié et PFS (Perfect Forward Secrecy). N'acceptez rien sur des connexions non HTTPS. Avoir le drapeau sécurisé sur les cookies.
En stockage : C'est plus difficile. Tout d'abord, vous devez réduire votre exposition. Si vous n'avez pas besoin de données sensibles, détruisez-les. Les données que vous n'avez pas ne peuvent pas être volées. Ne stockez jamais les informations de carte de crédit, car vous ne voulez probablement pas avoir à vous soucier d'être conforme à la norme PCI. Inscrivez-vous auprès d'un processeur de paiement tel que Stripe ou Braintree. Deuxièmement, si vous avez des données sensibles dont vous avez réellement besoin, stockez-les cryptées et assurez-vous que tous les mots de passe sont hachés. Pour le hachage, l'utilisation de bcrypt est recommandée. Si vous n'utilisez pas bcrypt, renseignez-vous sur les tables de salage et arc-en-ciel.
Et au risque d'énoncer une évidence, ne stockez pas les clés de chiffrement à côté des données protégées . C'est comme ranger votre vélo avec un cadenas dans lequel se trouve la clé. Protégez vos sauvegardes avec le cryptage et gardez vos clés très privées. Et bien sûr, ne perdez pas les clés !
Erreur courante de sécurité Web n° 7 : contrôle d'accès au niveau des fonctions manquant
Il s'agit simplement d'un échec d'autorisation. Cela signifie que lorsqu'une fonction est appelée sur le serveur, l'autorisation appropriée n'a pas été effectuée. Souvent, les développeurs s'appuient sur le fait que le côté serveur a généré l'interface utilisateur et ils pensent que la fonctionnalité qui n'est pas fournie par le serveur n'est pas accessible au client. Ce n'est pas aussi simple que cela, car un attaquant peut toujours falsifier des demandes à la fonctionnalité "cachée" et ne sera pas dissuadé par le fait que l'interface utilisateur ne rend pas cette fonctionnalité facilement accessible. Imaginez qu'il y ait un panneau /admin
et que le bouton ne soit présent dans l'interface utilisateur que si l'utilisateur est en fait un administrateur. Rien n'empêche un attaquant de découvrir cette fonctionnalité et de l'utiliser à mauvais escient si l'autorisation est manquante.
Prévention : Côté serveur, l'autorisation doit toujours être faite. Oui toujours. Aucune exception ou vulnérabilité n'entraînera de problèmes graves.
Erreur courante de sécurité Web n° 8 : falsification de requête intersite (CSRF)
Ceci est un bel exemple d'une attaque adjointe confuse dans laquelle le navigateur est trompé par une autre partie pour abuser de son autorité. Un site tiers, par exemple, peut amener le navigateur de l'utilisateur à abuser de son autorité pour faire quelque chose pour l'attaquant.
Dans le cas de CSRF, un site tiers envoie des requêtes au site cible (par exemple, votre banque) en utilisant votre navigateur avec vos cookies/session. Si vous êtes connecté sur un onglet de la page d'accueil de votre banque, par exemple, et qu'ils sont vulnérables à cette attaque, un autre onglet peut faire en sorte que votre navigateur utilise à mauvais escient ses informations d'identification au nom de l'attaquant, ce qui entraîne un problème d'adjoint confus. L'adjoint est le navigateur qui abuse de son autorité (cookies de session) pour faire quelque chose que l'attaquant lui demande de faire.
Considérez cet exemple :
L'attaquant Alice veut alléger le portefeuille de la cible Todd en lui transférant une partie de son argent. La banque de Todd est vulnérable au CSRF. Pour envoyer de l'argent, Todd doit accéder à l'URL suivante :
http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243
Une fois cette URL ouverte, une page de réussite est présentée à Todd et le transfert est effectué. Alice sait également que Todd visite fréquemment un site sous son contrôle sur blog.aliceisawesome.com, où elle place l'extrait suivant :
<img src=http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243 width=0 height=0 />
Lors de la visite du site Web d'Alice, le navigateur de Todd pense qu'Alice est lié à une image et émet automatiquement une requête HTTP GET pour récupérer l'image, mais cela ordonne en fait à la banque de Todd de transférer 1 500 $ à Alice.
Incidemment, en plus de démontrer la vulnérabilité CSRF, cet exemple montre également la modification de l'état du serveur avec une requête HTTP GET idempotente qui est elle-même une vulnérabilité sérieuse. Les requêtes HTTP GET doivent être idempotentes (sûres), ce qui signifie qu'elles ne peuvent pas modifier la ressource à laquelle on accède. N'utilisez jamais, jamais, jamais de méthodes idempotentes pour modifier l'état du serveur.
Fait amusant : CSRF est également la méthode utilisée par les gens pour bourrer les cookies dans le passé jusqu'à ce que les affiliés deviennent plus sages.
Prévention : stockez un jeton secret dans un champ de formulaire caché qui est inaccessible depuis le site tiers. Vous devez bien sûr toujours vérifier ce champ caché. Certains sites demandent également votre mot de passe lors de la modification de paramètres sensibles (comme votre e-mail de rappel de mot de passe, par exemple), même si je soupçonne que cela est là pour empêcher l'utilisation abusive de vos sessions abandonnées (dans un cybercafé par exemple).
Erreur courante de sécurité Web n° 9 : utiliser des composants présentant des vulnérabilités connues
Le titre dit tout. Je classerais à nouveau cela comme un problème de maintenance/déploiement. Avant d'incorporer un nouveau code, effectuez des recherches, éventuellement des audits. L'utilisation de code que vous avez obtenu d'une personne au hasard sur GitHub ou sur un forum peut être très pratique, mais n'est pas sans risque de grave vulnérabilité de sécurité Web.
J'ai vu de nombreux cas, par exemple, où des sites sont devenus propriétaires (c'est-à-dire lorsqu'un étranger obtient un accès administratif à un système), non pas parce que les programmeurs étaient stupides, mais parce qu'un logiciel tiers est resté sans correctif pendant des années en production. Cela arrive tout le temps avec les plugins WordPress par exemple. Si vous pensez qu'ils ne trouveront pas votre installation cachée de phpmyadmin
, laissez-moi vous présenter dirbuster.
La leçon ici est que le développement logiciel ne se termine pas lorsque l'application est déployée. Il doit y avoir une documentation, des tests et des plans sur la façon de le maintenir et de le maintenir à jour, surtout s'il contient des composants tiers ou open source.
La prévention:
Faites preuve de prudence. Au-delà évidemment de la prudence lors de l'utilisation de tels composants, ne soyez pas un codeur copier-coller. Inspectez soigneusement le morceau de code que vous êtes sur le point d'insérer dans votre logiciel, car il pourrait être irréparable (ou dans certains cas, intentionnellement malveillant - les attaques de sécurité Web sont parfois involontairement invitées de cette manière).
Tiens-toi à jour. Assurez-vous d'utiliser les dernières versions de tout ce en quoi vous avez confiance et prévoyez de les mettre à jour régulièrement. Abonnez-vous au moins à une newsletter sur les nouvelles vulnérabilités de sécurité concernant le produit.
Erreur courante de sécurité Web #10 : redirections et transferts non validés
Il s'agit encore une fois d'un problème de filtrage d'entrée. Supposons que le site cible ait un module redirect.php
qui prend une URL comme paramètre GET
. La manipulation du paramètre peut créer une URL sur targetsite.com
qui redirige le navigateur vers malwareinstall.com
. Lorsque l'utilisateur voit le lien, il verra targetsite.com/blahblahblah
lequel l'utilisateur pense qu'il est fiable et sur lequel il peut cliquer en toute sécurité. Ils ne savent pas que cela les transférera réellement sur une page de dépôt de logiciels malveillants (ou toute autre page malveillante). Alternativement, l'attaquant peut rediriger le navigateur vers targetsite.com/deleteprofile?confirm=1
.
Il convient de mentionner que le bourrage d'une entrée définie par l'utilisateur non nettoyée dans un en-tête HTTP peut entraîner une injection d'en-tête, ce qui est plutôt mauvais.
Prévention : les options comprennent :
- Ne faites pas de redirections du tout (elles sont rarement nécessaires).
- Avoir une liste statique d'emplacements valides vers lesquels rediriger.
- Ajoutez le paramètre défini par l'utilisateur à la liste blanche, mais cela peut être délicat.
Épilogue
J'espère que j'ai réussi à chatouiller un peu votre cerveau avec cet article et à introduire une bonne dose de paranoïa et de sensibilisation à la vulnérabilité de la sécurité des sites Web.
L'essentiel à retenir ici est que les pratiques logicielles séculaires existent pour une raison et ce qui s'appliquait à l'époque pour les débordements de mémoire tampon s'applique toujours aux chaînes marinées en Python aujourd'hui. Les protocoles de sécurité vous aident à écrire des programmes (plus) corrects, auxquels tous les programmeurs devraient aspirer.
Veuillez utiliser ces connaissances de manière responsable et ne testez pas les pages sans autorisation !
Pour plus d'informations et des attaques côté serveur plus spécifiques, consultez : https://www.owasp.org/index.php/Category:Attack.
Les commentaires sur ce message et ses conseils d'atténuation sont les bienvenus et appréciés. De futurs articles connexes sont prévus, en particulier sur la question des vulnérabilités de sécurité informatique par déni de service distribué (DDoS) et à l'ancienne (et non Web). Si vous avez une demande spécifique sur le type de protection Web à écrire, n'hésitez pas à me contacter directement à [email protected].
Place à la sécurité du site ! Acclamations.
- Tutoriel sur les jetons Web JSON : un exemple dans Laravel et AngularJS
- Performances et efficacité : travailler avec HTTP/3