Quelles sont les meilleures pratiques pour éviter les attaques xss sur un site PHP

StackOverflow https://stackoverflow.com/questions/71328

  •  09-06-2019
  •  | 
  •  

Question

J'ai configuré PHP pour que les guillemets magiques soient activés et les globaux de registre désactivés.

Je fais de mon mieux pour toujours appeler htmlentities () pour tout ce que je produis qui est dérivé de la saisie de l'utilisateur.

Je cherche aussi occasionnellement dans ma base de données des éléments courants utilisés dans xss, tels que ...

<script

Que dois-je faire d'autre et comment puis-je m'assurer que les choses que j'essaie de faire sont toujours faites.

Était-ce utile?

La solution

Échapper à une entrée n’est pas la meilleure solution pour une prévention réussie des XSS. La sortie doit également être échappée. Si vous utilisez le moteur de modèle Smarty, vous pouvez utiliser le modificateur |escape:'htmlall' pour convertir tous les caractères sensibles en entités HTML (j'utilise le modificateur |e qui est alias de ce qui précède).

Mon approche de la sécurité des entrées / sorties est la suivante:

  • entrée utilisateur du magasin non modifiée (pas d’échappement HTML sur l’entrée, seulement un échappement conscient de la base de données effectué via des instructions préparées PDO)
  • échappe à la sortie, en fonction du format de sortie utilisé (par exemple, HTML et JSON nécessitent des règles d'échappement différentes)

Autres conseils

Je suis d’avis qu’il ne faut rien échapper lors de la saisie, mais uniquement lors de la sortie. Depuis (la plupart du temps), vous ne pouvez pas supposer que vous savez où vont ces données. Par exemple, si vous avez un formulaire qui prend des données qui apparaissent plus tard dans un courrier électronique que vous envoyez, vous avez besoin d'un échappement différent (sinon, un utilisateur malveillant pourrait réécrire vos en-têtes de courrier électronique).

En d'autres termes, vous ne pouvez vous échapper qu'au tout dernier moment où les données sont & "Laissant &"; votre application:

  • Élément de liste
  • Écrire dans un fichier XML, échapper pour XML
  • Écrire dans la base de données, échapper (pour ce SGBD particulier)
  • Écrire un e-mail, échapper pour recevoir des e-mails
  • etc

Pour faire court:

  1. Vous ne savez pas où vont vos données
  2. Les données peuvent en réalité se retrouver à plus d'un endroit, nécessitant des mécanismes d'échappement différents, MAIS PAS LES DEUX
  3. Les données échappées pour la mauvaise cible ne sont vraiment pas agréables. (Par exemple, recevez un e-mail avec le sujet & Quot; aller au bar de Tommy & Quot;.)

Esp # 3 se produira si vous échappez des données au niveau de la couche d'entrée (ou si vous avez besoin de les échapper à nouveau, etc.).

PS: J'appuie le conseil pour ne pas utiliser magic_quotes, ce sont des maux purs!

Il existe de nombreuses façons de faire XSS (voir http://ha.ckers.org/xss .html ) et il est très difficile à attraper.

Je délègue personnellement ceci au framework actuel que j'utilise (Code Igniter par exemple). Bien que pas parfait, il pourrait attraper plus que mes routines faites à la main jamais.

C’est une excellente question.

Tout d'abord, n'échappez pas le texte lors de la saisie, sauf pour le rendre sûr pour le stockage (par exemple, le placer dans une base de données). La raison en est que vous souhaitez conserver ce qui a été entré afin de pouvoir le présenter de manière contextuelle de différentes manières et à différents endroits. Faire des changements ici peut compromettre votre présentation ultérieure.

Lorsque vous présentez votre filtre de données, éliminez ce qui ne devrait pas y figurer. Par exemple, si javascript n'a aucune raison d'être, recherchez-le et supprimez-le. Un moyen facile de le faire consiste à utiliser la fonction strip_tags et à ne présenter que les balises HTML que vous autorisez.

Ensuite, prenez ce que vous avez et transmettez-le à htmlentities ou htmlspecialchars pour changer ce qu’il ya en caractères ascii. Faites ceci en fonction du contexte et de ce que vous voulez sortir.

Je suggérerais également de désactiver Magic Quotes. Il a été retiré de PHP 6 et est considéré comme une mauvaise pratique. Détails sur http://us3.php.net/magic_quotes

Pour plus de détails, consultez http://ha.ckers.org/xss.html .

Ce n'est pas une réponse complète mais, espérons-le, suffisante pour vous aider à démarrer.

  

rikh écrit:

     
    

Je fais de mon mieux pour toujours appeler htmlentities () pour tout ce que je produis qui est dérivé de la saisie de l'utilisateur.

  

Voir l'essai de Joel sur Rendre le code incorrect, pour obtenir de l'aide à cet égard

Je me fie à PHPTAL pour cela.

Contrairement à Smarty et à PHP pur, il échappe par défaut à toutes les sorties. C'est une grande victoire pour la sécurité, car votre site ne deviendra pas visible si vous oubliez htmlspecialchars() ou |escape quelque part.

XSS étant une attaque spécifique à HTML, la sortie HTML est le bon endroit pour l’empêcher. Vous ne devez pas essayer de pré-filtrer les données de la base de données, car vous pourriez avoir besoin de les exporter sur un autre support qui n'accepte pas le HTML, mais comporte ses propres risques.

Bibliothèque de modèles. Ou du moins, c'est ce que les bibliothèques de modèles doivent faire. Pour empêcher XSS toutes les sorties doivent être codées. Ce n’est pas la tâche de la logique principale d’application / contrôle, elle doit être gérée uniquement par les méthodes de sortie.

Si vous saupoudrez des balises htmlentities () dans votre code, la conception globale est fausse. Et comme vous le suggérez, vous risquez de manquer un ou deux points. C'est pourquoi la seule solution est un codage HTML rigoureux - & Gt; lorsque les vars en sortie sont écrits dans un flux html / xml.

Malheureusement, la plupart des bibliothèques de modèles php ajoutent seulement leur propre syntaxe de modèle, mais ne se préoccupent pas du codage en sortie, de la localisation, de la validation html ou de tout autre élément important. Peut-être que quelqu'un d'autre connaît une bibliothèque de modèles appropriée pour php?

Échapper à toutes les entrées d'utilisateur est suffisant pour la plupart des sites. Assurez-vous également que les identifiants de session ne se retrouvent pas dans l'URL afin qu'ils ne puissent pas être volés du lien Referer vers un autre site. De plus, si vous autorisez vos utilisateurs à soumettre des liens, assurez-vous qu'aucun lien de protocole javascript: n'est autorisé; ceux-ci exécuteraient un script dès que l'utilisateur clique sur le lien.

Si vous êtes préoccupé par les attaques XSS, coder vos chaînes de sortie en HTML est la solution. Si vous vous souvenez d’encoder chaque caractère de sortie au format HTML, il n’ya aucun moyen d’exécuter une attaque XSS avec succès.

Lire la suite: Désinfection des données utilisateur: Comment et où le faire

Personnellement, je désactiverais magic_quotes. En PHP5 +, il est désactivé par défaut et il est préférable de coder comme si ce n’était pas du tout car il n’échappait pas à tout et il serait supprimé de PHP6.

Ensuite, en fonction du type de données utilisateur que vous filtrez, cela dictera la marche à suivre, par exemple. s'il ne s'agit que de texte, par exemple un nom, puis strip_tags(trim(stripslashes())); le ou pour vérifier les plages, utilisez des expressions régulières.

Si vous attendez une certaine plage de valeurs, créez un tableau des valeurs valides et n'autorisez ces valeurs que par (in_array($userData, array(...))).

Si vous vérifiez les nombres, utilisez is_numeric pour appliquer des nombres entiers ou une conversion vers un type spécifique, ce qui devrait empêcher les utilisateurs d'essayer d'envoyer des chaînes à la place.

Si vous avez PHP 5.2 +, envisagez de regarder filter () et de vous en servir. extension qui peut filtrer divers types de données, y compris les adresses électroniques. La documentation n’est pas particulièrement bonne mais s’améliore.

Si vous devez gérer le langage HTML, vous devez envisager un filtre de saisie PHP. ou purificateur HTML . HTML Purifier validera également le code HTML pour la conformité. Je ne suis pas sûr si le filtre d'entrée est encore en cours de développement. Les deux vous permettront de définir un ensemble de balises pouvant être utilisées et les attributs autorisés.

Quoi que vous décidiez, souvenez-vous toujours de ne jamais faire confiance à quoi que ce soit qui entre dans votre script PHP par un utilisateur (y compris vous-même!).

Toutes ces réponses sont bonnes, mais fondamentalement, la solution à XSS consistera à arrêter de générer des documents HTML par manipulation de chaînes.

Le filtrage des entrées est toujours une bonne idée pour toute application.

Échapper votre sortie en utilisant htmlentities () et amis devrait fonctionner tant qu'il est utilisé correctement, mais c'est l'équivalent HTML de créer une requête SQL en concaténant des chaînes avec mysql_real_escape_string ($ var) - cela devrait fonctionner, mais moins de choses peuvent pour ainsi dire, validez votre travail par rapport à une approche telle que l’utilisation de requêtes paramétrées.

La solution à long terme devrait être que les applications construisent la page en interne, éventuellement à l'aide d'une interface standard telle que le DOM, puis utilisent une bibliothèque (telle que libxml) pour gérer la sérialisation vers XHTML / HTML / etc. Bien sûr, nous sommes loin de cette popularité et de notre rapidité, mais nous devons construire nos documents HTML via des opérations sur les chaînes de caractères, ce qui est intrinsèquement plus risqué.

Je trouve que l'utilisation de cette fonction permet d'éliminer de nombreuses attaques xss possibles: http://www.codebelay.com/killxss.phps

& # 8220; Citations magiques & # 8221; est un remède palliatif à certains des pires défauts XSS qui fonctionne en évitant tout en entrée, quelque chose qui ne va pas de soi. Le seul cas où vous souhaiteriez l'utiliser est le cas où vous devez absolument utiliser une application PHP existante connue pour avoir été écrite sans précaution en ce qui concerne XSS. (Dans ce cas, vous rencontrez des problèmes graves même avec & # 8220; citations magiques & # 8221 ;.) lors du développement de votre propre application, vous devez désactiver & # 8220; citations magiques & #. 8221; et suivez les pratiques XSS-safe à la place.

XSS, une vulnérabilité de script intersite, se produit lorsqu'une application inclut des chaînes de sources externes (entrée utilisateur, extraites d'autres sites Web, etc.) dans ses fichiers [X] HTML, CSS, ECMAscript ou toute autre sortie analysée par navigateur d'échappement, en espérant que des caractères spéciaux tels que less-than (en [X] HTML), guillemets simples ou doubles (ECMAscript) n'apparaîtront jamais. La solution appropriée consiste à toujours échapper les chaînes conformément aux règles du langage de sortie: utilisation d’entités dans [X] HTML, de barres obliques inverses dans ECMAscript, etc.

Parce qu'il peut être difficile de garder une trace de ce qui n'est pas fiable et doit être échappé, c'est une bonne idée de toujours échapper à tout ce qui est une chaîne de texte & # 8220; & # 8221; par opposition à & # 8220; texte avec balise & # 8221; dans un langage comme HTML. Certains environnements de programmation facilitent la tâche en introduisant plusieurs types de chaînes incompatibles: & # 8220; string & # 8221; (texte normal), & # 8220; Chaîne HTML & # 8221; (Balise HTML) et ainsi de suite. De cette façon, une conversion implicite directe de & # 8220; chaîne & # 8221; to & # 8220; Chaîne HTML & # 8221; serait impossible, et la seule façon pour une chaîne de devenir un balisage HTML est de la transmettre à une fonction d'échappement.

& # 8220; Enregistrer les paramètres globaux & # 8221 ;, bien que le désactiver soit définitivement une bonne idée, traite un problème totalement différent de XSS.

Vous créez des cookies de session (ou tous les cookies) que vous utilisez avec HttpOnly. La plupart des navigateurs masqueront la valeur du cookie à JavaScript dans ce cas. L'utilisateur peut toujours copier manuellement les cookies, mais cela permet d'éviter l'accès direct au script. StackOverflow a rencontré ce problème en bêta.

Ce n'est pas une solution, mais une autre brique dans le mur

  • Ne faites pas confiance aux entrées de l'utilisateur
  • Échapper à toute sortie de texte libre
  • N'utilisez pas magic_quotes; voir s'il existe une variante spécifique au SGBD ou utiliser PDO
  • Si possible, utilisez des cookies HTTP uniquement pour éviter à tout script malveillant de détourner une session

Vous devez au moins valider toutes les données entrant dans la base de données. Et essayez également de valider toutes les données quittant la base de données.

mysql_real_escape_string est utile pour empêcher l’injection SQL, mais XSS est plus délicat. Vous devriez preg_match, stip_tags ou htmlentities si possible!

La meilleure méthode actuelle pour empêcher XSS dans une application PHP est HTML Purifier (http://htmlpurifier.org/). Un inconvénient mineur, c’est qu’il s’agit d’une bibliothèque assez volumineuse et qu’elle est mieux utilisée avec un cache de code op comme APC. Vous l'utiliserez à tout endroit où du contenu non fiable est affiché à l'écran. Il est beaucoup plus complet que htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags, etc.

Utilisez une bibliothèque de désinfection existante entrée utilisateur pour nettoyer toutes les entrées utilisateur. À moins que vous ne consacriez beaucoup d'efforts, sa mise en oeuvre vous-même ne fonctionnera jamais aussi bien.

Je trouve que le meilleur moyen consiste à utiliser une classe qui vous permet de lier votre code afin que vous n'ayez jamais à vous soucier de fuir manuellement vos données.

Il est difficile de mettre en œuvre une prévention complète des injections SQL / XSS sur un site qui ne provoque pas de fausses alarmes. Dans un CMS, l'utilisateur final peut vouloir utiliser <script> ou <object> qui relie à des éléments d'un autre site.

Je recommande que tous les utilisateurs installent FireFox avec NoScript; -)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top