J'ai PHP configuré pour que les guillemets magiques soient activés et que les registres globaux soient désactivés.
Je fais de mon mieux pour toujours appeler htmlentities () pour tout ce que je génère et qui est dérivé de l'entrée utilisateur.
Je recherche également occasionnellement ma base de données pour les choses courantes utilisées dans xss jointes telles que ...
<script
Que dois-je faire d'autre et comment puis-je m'assurer que les choses que j'essaie de faire sont toujours terminées.
Échapper à l'entrée n'est pas le meilleur que vous puissiez faire pour une prévention XSS réussie. La sortie doit également être échappée. Si vous utilisez le moteur de modèle Smarty, vous pouvez utiliser |escape:'htmlall'
modificateur pour convertir tous les caractères sensibles en entités HTML (j'utilise son propre |e
modificateur qui est un alias de ce qui précède).
Mon approche de la sécurité des entrées/sorties est la suivante:
Je suis d'avis qu'il ne faut rien échapper lors de l'entrée, seulement en 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 e-mail que vous envoyez, vous avez besoin d'un échappement différent (sinon un utilisateur malveillant pourrait réécrire vos en-têtes d'e-mail).
En d'autres termes, vous ne pouvez échapper qu'au tout dernier moment où les données "quittent" votre application:
Pour faire court:
Esp # 3 se produira si vous échappez des données à la couche d'entrée (ou si vous avez besoin de les échapper à nouveau, etc.).
PS: je vais seconder les conseils pour ne pas utiliser magic_quotes, ce sont des pires mal!
Il y a beaucoup de façons de faire XSS (Voir http://ha.ckers.org/xss.html ) et c'est très difficile à attraper.
Je délègue personnellement cela au framework actuel que j'utilise (Code Igniter par exemple). Bien qu'il ne soit pas parfait, il pourrait attraper plus que mes routines faites à la main.
C'est une excellente question.
Tout d'abord, n'échappez pas au texte en entrée, sauf pour le rendre sûr pour le stockage (comme être placé 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 contextuellement de différentes manières et à différents endroits. Faire des changements ici peut compromettre votre présentation ultérieure.
Lorsque vous allez présenter votre filtre de données sur ce qui ne devrait pas y être. Par exemple, s'il n'y a pas de raison pour que javascript soit là, recherchez-le et supprimez-le. Un moyen simple de le faire est d'utiliser la fonction strip_tags et de ne présenter que les balises html que vous autorisez.
Ensuite, prenez ce que vous avez et passez-le en pensant htmlentities ou htmlspecialchars pour changer ce qui est là en caractères ascii. Pour ce faire, en fonction du contexte et de ce que vous souhaitez retirer.
Je suggère également de désactiver Magic Quotes. Il a été supprimé de PHP 6 et est considéré comme une mauvaise pratique pour l'utiliser. 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, assez pour vous aider à démarrer.
je fais de mon mieux pour toujours appeler htmlentities () pour tout ce que je génère et qui est dérivé de l'entrée utilisateur.
.
See Joel's essay on Making Code Look Wrong for help with this
Je compte sur PHPTAL pour cela.
Contrairement à Smarty et à PHP simple, il échappe à toutes les sorties par défaut. C'est une grande victoire pour la sécurité, car votre site ne deviendra pas vurnelable si vous oubliez htmlspecialchars()
ou |escape
quelque part.
XSS est une attaque spécifique à HTML, donc la sortie HTML est le bon endroit pour l'empêcher. Vous ne devriez pas essayer de pré-filtrer les données dans la base de données, car vous pourriez avoir besoin de produire des données sur un autre support qui n'accepte pas le HTML, mais qui a ses propres risques.
Bibliothèque de modèles. Ou du moins, c'est ce que les bibliothèques de modèles devraient faire. Pour empêcher XSS toutes les sorties doivent être encodées. Ce n'est pas la tâche de la logique principale d'application/de contrôle, elle doit uniquement être gérée par les méthodes de sortie.
Si vous saupoudrez htmlentities () dans votre code, la conception générale est incorrecte. 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 -> lorsque les variables de sortie sont écrites dans un flux html/xml.
Malheureusement, la plupart des bibliothèques de modèles php n'ajoutent que leur propre syntaxe de modèle, mais ne se soucient pas du codage de sortie, de la localisation, de la validation html ou de quoi que ce soit d'important. Peut-être que quelqu'un d'autre connaît une bibliothèque de modèles appropriée pour PHP?
Si vous êtes préoccupé par les attaques XSS, le codage de 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'y a aucun moyen d'exécuter une attaque XSS réussie.
En savoir plus: Sanitizing user data: How and where to do it
Personnellement, je désactiverais magic_quotes. En PHP5 +, il est désactivé par défaut et il vaut mieux coder comme s'il n'était pas là du tout car il n'échappe pas à tout et il sera supprimé de PHP6.
Ensuite, selon le type de données utilisateur que vous filtrez, vous dicterez quoi faire ensuite, par exemple si c'est juste du texte par ex. un nom, puis strip_tags(trim(stripslashes()));
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 autorisez uniquement ces valeurs via (in_array($userData, array(...))
).
Si vous vérifiez les nombres, utilisez is_numeric pour appliquer des nombres entiers ou transtyper en un type spécifique, cela devrait empêcher les gens d'essayer d'envoyer des chaînes à la place.
Si vous avez PHP5.2 +, pensez à regarder filter () et à utiliser cette extension qui peut filtrer divers types de données, y compris les adresses e-mail. La documentation n'est pas particulièrement bonne, mais s'améliore.
Si vous devez gérer le HTML, vous devriez envisager quelque chose comme Filtre d'entrée PHP ou Purificateur HTML . HTML Purifier validera également HTML pour la conformité. Je ne sais pas si le filtre d'entrée est toujours 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, rappelez-vous toujours, ne faites jamais confiance à quoi que ce soit entrant dans votre script PHP d'un utilisateur (vous y compris!).
Je trouve que l'utilisation de cette fonction aide à éliminer un grand nombre d'attaques xss possibles: http://www.codebelay.com/killxss.phps
"Magic quotes" est un remède palliatif à certains des pires défauts XSS qui fonctionne en échappant à tout en entrée, quelque chose qui ne va pas par conception. Le seul cas où l'on voudrait l'utiliser est lorsque vous devez absolument utiliser une application PHP connue pour être écrite négligemment en ce qui concerne XSS. (Dans ce cas, vous avez de sérieux problèmes) même avec des "guillemets magiques".) Lorsque vous développez votre propre application, vous devez désactiver les "guillemets magiques" et suivre à la place les pratiques XSS-safe.
XSS, une vulnérabilité de script intersite, se produit lorsqu'une application inclut des chaînes de sources externes (entrée utilisateur, récupérées à partir d'autres sites Web, etc.) dans ses [X] HTML, CSS, ECMAscript ou autre sortie analysée par navigateur sans échappement approprié, en espérant que les caractères spéciaux comme moins que (en [X] HTML), les guillemets simples ou doubles (ECMAscript) n'apparaîtront jamais. La bonne solution consiste à toujours échapper les chaînes selon les règles du langage de sortie: utilisation d'entités en [X] HTML, barres obliques inverses en ECMAscript, etc.
Parce qu'il peut être difficile de garder une trace de ce qui n'est pas approuvé et doit être échappé, c'est une bonne idée de toujours échapper tout ce qui est une "chaîne de texte" par opposition à "texte avec balisage" dans une langue comme HTML. Certains environnements de programmation facilitent la tâche en introduisant plusieurs types de chaînes incompatibles: "chaîne" (texte normal), "chaîne HTML" (balisage HTML), etc. De cette façon, une conversion implicite directe de "chaîne" en "chaîne HTML" serait impossible, et la seule façon dont une chaîne pourrait devenir un balisage HTML est de la passer à travers une fonction d'échappement.
"Register globals", bien que la désactiver soit définitivement une bonne idée, traite un problème entièrement différent de XSS.
Échapper à toutes les entrées utilisateur est suffisant pour la plupart des sites. Assurez-vous également que les ID 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 à envoyer des liens, assurez-vous qu'aucun javascript:
les liaisons de protocole sont autorisées; ceux-ci exécuteraient un script dès que l'utilisateur clique sur le lien.
Toutes ces réponses sont excellentes, mais fondamentalement, la solution à XSS sera d'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 n'importe quelle application.
Échapper votre sortie à l'aide de htmlentities () et d'amis devrait fonctionner tant qu'elle est utilisée correctement, mais c'est l'équivalent HTML de la création d'une requête SQL en concaténant des chaînes avec mysql_real_escape_string ($ var) - cela devrait fonctionner, mais moins de choses peuvent valider votre travail , pour ainsi dire, par rapport à une approche comme l'utilisation de requêtes paramétrées.
La solution à long terme devrait être pour les applications de construire la page en interne, peut-être en utilisant une interface standard comme le DOM, puis d'utiliser une bibliothèque (comme libxml) pour gérer la sérialisation en XHTML/HTML/etc. Bien sûr, nous sommes loin de ce qui est populaire et assez rapide, mais en attendant, nous devons construire nos documents HTML via des opérations de chaîne, et c'est intrinsèquement plus risqué.
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 bon 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 est que c'est une bibliothèque assez grande et qu'il vaut mieux l'utiliser avec un cache de code op comme APC. Vous pouvez l'utiliser dans n'importe quel endroit où du contenu non approuvé est affiché à l'écran. Il est beaucoup plus approfondi que htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags, etc.
Vous faire tous les cookies de session (ou tous les cookies) que vous utilisez HttpOnly. La plupart des navigateurs masqueront la valeur du cookie de JavaScript dans ce cas. L'utilisateur peut toujours copier manuellement les cookies, mais cela empêche l'accès direct au script. StackOverflow a eu ce problème pendant la version bêta.
Ce n'est pas une solution, juste une autre brique dans le mur
Je trouve que la meilleure façon est d'utiliser une classe qui vous permet de lier votre code afin que vous n'ayez jamais à vous soucier d'échapper manuellement vos données.
Utilisez une bibliothèque de nettoyage des entrées utilisateur existante pour nettoyer tous entrée utilisateur. À moins d'y consacrer beaucoup d'efforts, sa mise en œuvre vous-même ne fonctionnera jamais aussi bien.