web-dev-qa-db-fra.com

Sécuriser un grand et ancien site de commerce électronique de XSS?

Je travaille pour un site de commerce électronique écrit en C # .net (pas de CMS utilisé, beaucoup de code) où la sécurité n'a pas été une priorité depuis longtemps. Ma mission en ce moment est de trouver et de réparer toutes les violations XSS. Il y a beaucoup de données non filtrées écrites directement dans le HTML rendu.

Quelle est ma meilleure stratégie pour guérir le code sans avoir à lire chaque page?

16
kyori

Je propose le programme en quatre étapes suivant, où vous choisissez d'abord les fruits qui pendent bas pour vous donner un minimum de protection pendant que vous travaillez sur les plus gros problèmes.

1. Activer le filtrage côté client

1.1 Définir l'en-tête X-XSS-Protection

La définition de l'en-tête de réponse HTTP suivant activera les navigateurs intégrés à la protection XSS:

X-XSS-Protection: 1; mode=block

Ce n'est en aucun cas étanche, et cela n'aide que contre les XSS réfléchis, mais c'est quelque chose. Certaines anciennes versions de IE (surprise, surprise) ont un filtre buggy qui pourrait en fait aggraver les choses, donc vous voudrez peut-être filtrer certains agents utilisateurs.

1.2 Définir une politique de sécurité du contenu

Si vous n'utilisez pas JavaScript en ligne dans votre application, un CSP peut beaucoup aider. La définition de script-src 'self' (A) limitera les balises de script pour inclure uniquement les scripts de votre propre domaine, et (b) désactivera les scripts en ligne. Donc même si un attaquant pouvait injecter <img onerror="alert('XSS')"> le navigateur n'exécuterait pas le script. Vous devrez adapter la valeur que vous utilisez pour l'en-tête à votre propre utilisation, mais la ressource MDN liée devrait vous y aider.

Mais encore une fois, ce n'est pas étanche. Il ne fait rien pour aider les utilisateurs avec un navigateur qui n'implémente pas CSP (voir ici ). Et si votre source est jonchée de scripts en ligne, vous devrez choisir entre le nettoyer ou vous abstenir d'utiliser CSP.

2. Activez le filtrage côté serveur

John W a une bonne suggestion dans les commentaires:

De plus, comme il s'agit de .NET, un changement très rapide et facile peut activer ASP.NET Request Validation qui peut attraper une variété d'attaques XSS (mais pas 100% d'entre elles).

Si vous travaillez dans une autre langue, vous pourriez plutôt envisager d'utiliser un pare-feu d'application Web (comme suggéré par xehpuk ). La facilité de configuration d'un WAF dépend de l'application que vous protégez. Si vous faites des choses qui rendent le filtrage intrinsèquement difficile (par exemple, passez HTML dans GET ou POST), cela ne vaut peut-être pas la peine d'en configurer un.

Mais encore une fois, bien qu'un WAF puisse aider, il n'est toujours pas étanche.

3. Scannez et corrigez

Utilisez un scanner XSS automatisé pour trouver les vulnérabilités existantes et les corriger. En complément, vous pouvez exécuter vos propres tests manuels. Cela vous aidera à concentrer votre temps précieux sur la correction des vulnérabilités faciles à trouver, vous offrant le meilleur rapport qualité-prix au début.

Mais pour la troisième fois, ce n'est pas étanche. Peu importe combien vous numérisez et testez, vous manquerez quelque chose. Donc, malheureusement, il y a un point # 4 à cette liste ...

4. Nettoyez votre code source

Oui, vous "devrez lire chaque page". Parcourez la source et réécrivez tout le code qui génère des données à l'aide d'un cadre ou d'une bibliothèque de modèles qui gère les problèmes XSS de manière saine. (Vous devriez probablement choisir un framework et commencer à l'utiliser pour les correctifs que vous faites déjà sous # 3.)

Cela prendra beaucoup de temps, et ce sera une douleur dans le a **, mais cela doit être fait. Regardez-le du bon côté - vous avez la possibilité de faire quelques refactoring supplémentaires pendant que vous y êtes. En fin de compte, non seulement vous aurez résolu votre problème de sécurité, mais vous aurez également une meilleure base de code.

38
Anders

Le fait est qu'il n'y a pas de solution facile. J'ai une suggestion pour une solution "facile" au fond, mais gardez à l'esprit qu'elle a de nombreuses mises en garde, dont je vais discuter ici. Tout d'abord, commençons par la vue d'ensemble et descendons.

D'après mon expérience (ayant travaillé avec de nombreux systèmes hérités) "la sécurité n'a pas été une priorité depuis longtemps" signifie que vous avez probablement un certain nombre de problèmes de sécurité qui se cachent dans votre système. XSS n'est qu'un problème, j'en suis sûr. Donc, à moins que vous ne sachiez que quelqu'un est déjà au-dessus de cela, je me préoccuperais de:

  1. Sécurité par mot de passe. Je doute que vous hachiez selon les normes de sécurité modernes, et c'est un problème critique qui est autrement facilement ignoré.
  2. Sécurité de carte de crédit. J'espère que vous êtes conforme PCI et que vous ne stockez pas de cartes de crédit sur place. J'ai vu de nombreux systèmes hérités qui stockent les cartes de crédit, même si vous n'êtes pas censé le faire.
  3. SQLi est probablement un vrai problème, et est particulièrement dangereux si vous stockez des mots de passe de manière non sécurisée ou des cartes de crédit dans votre base de données.
  4. Vulnérabilités XSS!

Les chiffres ne sont pas censés impliquer la priorité: ils sont tous des priorités absolues.

Le point de départ

La chose la plus importante est de corriger cela "institutionnellement". Ce sera le plus difficile à faire, mais aussi le plus critique. Si vous passez quelques semaines à corriger toutes vos vulnérabilités XSS, mais que la sécurité continue d'être une priorité de bas niveau, le problème va juste revenir la prochaine fois qu'un développeur sortira des données non filtrées vers le navigateur.

La meilleure protection contre les vulnérabilités XSS est d'avoir des développeurs qui savent prendre la sécurité au sérieux et d'utiliser un moteur de modèles qui gère correctement les échappements XSS pour vous. La clé à retenir est qu'avec XSS, vous devez filtrer sur la sortie, pas sur l'entrée. Il est facile de voir cela comme un problème à sens unique "Nettoyez les données utilisateur lorsqu'elles entrent dans l'entrée, et alors vous êtes bon". Mais cela ne protège pas contre tous les vecteurs d'attaque, en particulier XSS ajouté via SQLi. En général, cependant, si la protection XSS est quelque chose que vos développeurs doivent faire à chaque fois, cela finira par être oublié. C'est pourquoi votre meilleur pari est d'avoir cette protection XSS intégrée à votre système. C'est là qu'intervient un moteur de modèles. Tout système de modèles compétent applique automatiquement le filtrage XSS par défaut, et doit être spécifiquement informé s'il doit pas filtrer pour XSS.

Je suis sûr que la refactorisation de votre système pour inclure un moteur de modèle spécifiquement pour prendre en charge les vulnérabilités XSS ne se produira probablement pas, mais il est également important de comprendre que si vous ne faites rien pour résoudre le problème institutionnel qui a permis cela se produire en premier lieu, le problème va juste revenir, et les semaines qu'il vous faudra pour résoudre ce problème seront perdues.

Premières étapes pratiques

@Anders a d'excellents points de départ dans sa réponse. Un CSP et l'en-tête XSS fonctionnent tous les deux de la même manière: en disant au navigateur d'activer la protection côté client XSS. Gardez à l'esprit (comme @Anders l'a mentionné) que ceux-ci dépendent du navigateur et, en particulier pour les navigateurs plus anciens, peuvent ne pas être pris en charge du tout. En particulier, la prise en charge d'IE pour CSP est très minime, même jusqu'à IE11 ( https://stackoverflow.com/questions/42937146/content-security-policy-does-not-work-in-internet -Explorateur-11 )

Le résultat est que même si ces étapes sont de bons points de départ, vous ne pouvez certainement pas vous y fier en tant que sécurité principale: vous devez toujours résoudre le problème de votre côté. Obtenir un bon outil de numérisation automatisé est certainement la meilleure façon de commencer. Il vous obtiendra des éléments d'action immédiate.

Une solution partielle

Une autre option que vous pourriez avoir est de mettre le filtrage XSS à travers le conseil d'administration sur votre application. Je ne recommande généralement pas cela, mais je pense que le meilleur pari pour vous est une réponse à plusieurs niveaux. L'idée ici est que vous ajoutez du code au processus d'amorçage de vos applications qui vérifie toutes les données entrantes du client (données url, POST, cookies, en-têtes REQUEST, etc ...). Vous puis effectuez un filtrage pour détecter les charges utiles XSS courantes et, s'il est trouvé, rejetez la demande tous ensemble.

Le problème avec le filtrage des listes noires est qu'il peut être très peu fiable. Si vous lisez la Aide-mémoire sur l'évasion du filtre OWASP XSS , vous aurez une bonne idée de la difficulté de filtrer les vulnérabilités XSS de manière fiable. Cependant, c'est un moyen rapide d'obtenir une protection à chaque demande, donc cela peut valoir la peine dans votre cas. Un problème important à garder à l'esprit est que cela empêchera généralement les éditeurs WYSIWYG de fonctionner. Cela peut ou non être un problème pour vous.

5
Conor Mancone