Comment empêcher XSS (cross-site scripting) d'utiliser uniquement HTML et PHP?
J'ai vu de nombreux autres articles sur ce sujet, mais je n'ai pas trouvé d'article qui indique clairement et de manière concise comment réellement empêcher XSS.
Juste une note que cela ne résoudra pas le cas où vous voudrez peut-être utiliser la saisie utilisateur comme attribut HTML. Par exemple, l'URL source d'une image. Pas un cas courant, mais facile à oublier.
Il y a un bel article ici qui explique XSS et comment l'empêcher dans différentes langues (y compris PHP).
XCore
Réponses:
296
Fondamentalement, vous devez utiliser la fonction htmlspecialchars()chaque fois que vous souhaitez sortir quelque chose dans le navigateur provenant de l'entrée utilisateur.
La bonne façon d'utiliser cette fonction est quelque chose comme ceci:
@TimTim: Pour la plupart des cas, oui. Cependant, lorsque vous devez autoriser l'entrée HTML, les choses deviennent un peu plus compliquées et si tel est le cas, je vous recommande d'utiliser quelque chose comme htmlpurifier.org
Alix Axel
@Alix Axel, votre réponse est-elle donc d'utiliser htmlspecialchars ou d'utiliser htmlpurifier.org ?
TimTim
3
Si vous devez accepter une entrée HTML, utilisez HTML Purifier, sinon utilisez-le htmlspecialchars().
La plupart du temps, c'est correct, mais ce n'est pas aussi simple que cela. Vous devriez envisager de mettre une chaîne non approuvée en HTML, Js, Css et envisager de mettre du HTML non approuvé en HTML. Regardez ceci: owasp.org/index.php/…
homme de bronze
41
L'une de mes références OWASP préférées est l' explication Cross-Site Scripting car bien qu'il existe un grand nombre de vecteurs d'attaque XSS, les quelques règles suivantes peuvent se défendre contre la majorité d'entre elles considérablement!
L'une des étapes les plus importantes consiste à nettoyer toute entrée utilisateur avant qu'elle ne soit traitée et / ou restituée au navigateur. PHP a quelques fonctions de " filtre " qui peuvent être utilisées.
La forme que les attaques XSS ont généralement consiste à insérer un lien vers du javascript hors site qui contient une intention malveillante pour l'utilisateur. En savoir plus ici .
Vous voudrez également tester votre site - je peux recommander le module complémentaire Firefox XSS Me .
De quoi ai-je besoin pour m'assurer de désinfecter exactement l'entrée. Y a-t-il un caractère / chaîne particulier à surveiller?
TimTim
27
@TimTim - non. Toutes les entrées des utilisateurs doivent toujours être considérées comme intrinsèquement hostiles.
zombat
En outre, les données internes (employés, administrateur système, etc.) pourraient être dangereuses. Vous devez identifier et surveiller (avec la date d'enregistrement et l'utilisateur) les données affichées avec interprétation.
Samuel Dauzon
9
Par ordre de préférence:
Si vous utilisez un moteur de modèles (par exemple Twig, Smarty, Blade), vérifiez qu'il offre un échappement contextuel. Je sais par expérience que Twig le fait.{{ var|e('html_attr') }}
Si vous souhaitez autoriser HTML, utilisez HTML Purifier . Même si vous pensez que vous n'acceptez que Markdown ou ReStructuredText, vous souhaitez toujours purifier le HTML de sortie de ces langages de balisage.
Sinon, utilisez htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)et assurez-vous que le reste de votre document utilise le même jeu de caractères que $charset. Dans la plupart des cas, 'UTF-8'c'est le jeu de caractères souhaité.
Publication croisée en tant que référence consolidée à partir de la version bêta de la documentation SO qui est mise hors ligne.
Problème
Les scripts intersites sont l'exécution involontaire de code à distance par un client Web. Toute application Web peut s'exposer à XSS si elle prend l'entrée d'un utilisateur et la renvoie directement sur une page Web. Si la saisie inclut HTML ou JavaScript, le code à distance peut être exécuté lorsque ce contenu est rendu par le client Web.
Par exemple, si un côté tiers contient un fichier JavaScript:
Le JavaScript tiers s'exécutera et l'utilisateur verra "Je cours" sur la page Web.
Solution
En règle générale, ne faites jamais confiance aux entrées provenant d'un client. Chaque valeur GET, POST et cookie peut être n'importe quoi et doit donc être validée. Lors de la sortie de l'une de ces valeurs, échappez-les afin qu'elles ne soient pas évaluées de manière inattendue.
Gardez à l'esprit que même dans les applications les plus simples, les données peuvent être déplacées et il sera difficile de garder une trace de toutes les sources. Par conséquent, il est recommandé de toujours échapper la sortie.
PHP fournit plusieurs façons d'échapper à la sortie en fonction du contexte.
htmlspecialcharsconvertira tous les "caractères spéciaux HTML" en leurs encodages HTML, ce qui signifie qu'ils ne seront alors pas traités comme du HTML standard. Pour corriger notre exemple précédent en utilisant cette méthode:
<?php
echo '<div>'. htmlspecialchars($_GET['input']).'</div>';// or
echo '<div>'. filter_input(INPUT_GET,'input', FILTER_SANITIZE_SPECIAL_CHARS).'</div>';
Tout ce qui se trouve à l'intérieur de la <div>balise ne sera pas interprété comme une balise JavaScript par le navigateur, mais plutôt comme un simple nœud de texte. L'utilisateur verra en toute sécurité:
Lors de la sortie d'une URL générée dynamiquement, PHP fournit la urlencodefonction pour sortir en toute sécurité des URL valides. Ainsi, par exemple, si un utilisateur est capable de saisir des données qui font partie d'un autre paramètre GET:
Toute entrée malveillante sera convertie en un paramètre d'URL codé.
Utilisation de bibliothèques externes spécialisées ou de listes OWASP AntiSamy
Parfois, vous souhaiterez envoyer du HTML ou d'autres types d'entrées de code. Vous devrez maintenir une liste de mots autorisés (liste blanche) et non autorisés (liste noire).
Vous pouvez télécharger les listes standard disponibles sur le site Web OWASP AntiSamy . Chaque liste est adaptée à un type spécifique d'interaction (ebay api, tinyMCE, etc ...). Et c'est open source.
Il existe des bibliothèques pour filtrer le HTML et empêcher les attaques XSS pour le cas général et effectuer au moins ainsi que les listes AntiSamy avec une utilisation très facile. Par exemple, vous avez HTML Purifier
De nombreux frameworks aident à gérer XSS de différentes manières. Lorsque vous lancez le vôtre ou en cas de problème XSS, nous pouvons tirer parti de filter_input_array (disponible en PHP 5> = 5.2.0, PHP 7.) J'ajoute généralement cet extrait à mon SessionController, car tous les appels passent par là avant tout autre contrôleur interagit avec les données. De cette manière, toutes les entrées utilisateur sont nettoyées dans 1 emplacement central. Si cela est fait au début d'un projet ou avant que votre base de données ne soit empoisonnée, vous ne devriez pas avoir de problèmes au moment de la sortie ... arrête les ordures, les ordures.
/* Prevent XSS input */
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);/* I prefer not to use $_REQUEST...but for those who do: */
$_REQUEST =(array)$_POST +(array)$_GET +(array)$_REQUEST;
Ce qui précède supprimera TOUTES les balises HTML et de script. Si vous avez besoin d'une solution qui autorise les balises sûres, basée sur une liste blanche, consultez HTML Purifier .
Si votre base de données est déjà empoisonnée ou si vous souhaitez gérer XSS au moment de la sortie, OWASP recommande de créer une fonction d'encapsuleur personnalisée pour echo, et de l'utiliser PARTOUT où vous produisez des valeurs fournies par l'utilisateur:
Vous pouvez également définir certains en-têtes de réponse HTTP liés à XSS via header(...)
X-XSS-Protection "1; mode = block"
pour être sûr, le mode de protection XSS du navigateur est activé.
Content-Security-Policy "default-src 'self'; ..."
pour activer la sécurité du contenu côté navigateur. Voir celui-ci pour plus de détails sur la politique de sécurité du contenu (CSP): http://content-security-policy.com/ La
configuration de CSP pour bloquer les scripts en ligne et les sources de script externes est particulièrement utile contre XSS.
Évitez également évidemment d'éviter eval(var), si vous devez utiliser l'un d'entre eux, essayez de les échapper JS , HTML les échapper et vous devrez peut-être en faire plus, mais pour les bases, cela devrait suffire.
href
ousrc
HTML: stackoverflow.com/questions/19047119/…Réponses:
Fondamentalement, vous devez utiliser la fonction
htmlspecialchars()
chaque fois que vous souhaitez sortir quelque chose dans le navigateur provenant de l'entrée utilisateur.La bonne façon d'utiliser cette fonction est quelque chose comme ceci:
Google Code University propose également ces vidéos très pédagogiques sur la sécurité Web:
Comment casser un logiciel Web - Un regard sur les failles de sécurité des logiciels Web
Ce que chaque ingénieur doit savoir sur la sécurité et où l'apprendre
la source
htmlspecialchars()
.L'une de mes références OWASP préférées est l' explication Cross-Site Scripting car bien qu'il existe un grand nombre de vecteurs d'attaque XSS, les quelques règles suivantes peuvent se défendre contre la majorité d'entre elles considérablement!
Ceci est une feuille de triche de sécurité PHP
la source
L'une des étapes les plus importantes consiste à nettoyer toute entrée utilisateur avant qu'elle ne soit traitée et / ou restituée au navigateur. PHP a quelques fonctions de " filtre " qui peuvent être utilisées.
La forme que les attaques XSS ont généralement consiste à insérer un lien vers du javascript hors site qui contient une intention malveillante pour l'utilisateur. En savoir plus ici .
Vous voudrez également tester votre site - je peux recommander le module complémentaire Firefox XSS Me .
la source
Par ordre de préférence:
{{ var|e('html_attr') }}
htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)
et assurez-vous que le reste de votre document utilise le même jeu de caractères que$charset
. Dans la plupart des cas,'UTF-8'
c'est le jeu de caractères souhaité.Assurez-vous également de vous échapper sur la sortie, pas sur l'entrée .
la source
Publication croisée en tant que référence consolidée à partir de la version bêta de la documentation SO qui est mise hors ligne.
Problème
Les scripts intersites sont l'exécution involontaire de code à distance par un client Web. Toute application Web peut s'exposer à XSS si elle prend l'entrée d'un utilisateur et la renvoie directement sur une page Web. Si la saisie inclut HTML ou JavaScript, le code à distance peut être exécuté lorsque ce contenu est rendu par le client Web.
Par exemple, si un côté tiers contient un fichier JavaScript:
Et une application PHP génère directement une chaîne qui lui est passée:
Si un paramètre GET non contrôlé contient
<script src="http://example.com/runme.js"></script>
alors la sortie du script PHP sera:Le JavaScript tiers s'exécutera et l'utilisateur verra "Je cours" sur la page Web.
Solution
En règle générale, ne faites jamais confiance aux entrées provenant d'un client. Chaque valeur GET, POST et cookie peut être n'importe quoi et doit donc être validée. Lors de la sortie de l'une de ces valeurs, échappez-les afin qu'elles ne soient pas évaluées de manière inattendue.
Gardez à l'esprit que même dans les applications les plus simples, les données peuvent être déplacées et il sera difficile de garder une trace de toutes les sources. Par conséquent, il est recommandé de toujours échapper la sortie.
PHP fournit plusieurs façons d'échapper à la sortie en fonction du contexte.
Fonctions de filtrage
Phps Fonctions Filter permettent les données d'entrée du script php pour être désinfecté ou validé à bien des égards . Ils sont utiles lors de l'enregistrement ou de la sortie des entrées client.
Encodage HTML
htmlspecialchars
convertira tous les "caractères spéciaux HTML" en leurs encodages HTML, ce qui signifie qu'ils ne seront alors pas traités comme du HTML standard. Pour corriger notre exemple précédent en utilisant cette méthode:Produirait:
Tout ce qui se trouve à l'intérieur de la
<div>
balise ne sera pas interprété comme une balise JavaScript par le navigateur, mais plutôt comme un simple nœud de texte. L'utilisateur verra en toute sécurité:Encodage d'URL
Lors de la sortie d'une URL générée dynamiquement, PHP fournit la
urlencode
fonction pour sortir en toute sécurité des URL valides. Ainsi, par exemple, si un utilisateur est capable de saisir des données qui font partie d'un autre paramètre GET:Toute entrée malveillante sera convertie en un paramètre d'URL codé.
Utilisation de bibliothèques externes spécialisées ou de listes OWASP AntiSamy
Parfois, vous souhaiterez envoyer du HTML ou d'autres types d'entrées de code. Vous devrez maintenir une liste de mots autorisés (liste blanche) et non autorisés (liste noire).
Vous pouvez télécharger les listes standard disponibles sur le site Web OWASP AntiSamy . Chaque liste est adaptée à un type spécifique d'interaction (ebay api, tinyMCE, etc ...). Et c'est open source.
Il existe des bibliothèques pour filtrer le HTML et empêcher les attaques XSS pour le cas général et effectuer au moins ainsi que les listes AntiSamy avec une utilisation très facile. Par exemple, vous avez HTML Purifier
la source
De nombreux frameworks aident à gérer XSS de différentes manières. Lorsque vous lancez le vôtre ou en cas de problème XSS, nous pouvons tirer parti de filter_input_array (disponible en PHP 5> = 5.2.0, PHP 7.) J'ajoute généralement cet extrait à mon SessionController, car tous les appels passent par là avant tout autre contrôleur interagit avec les données. De cette manière, toutes les entrées utilisateur sont nettoyées dans 1 emplacement central. Si cela est fait au début d'un projet ou avant que votre base de données ne soit empoisonnée, vous ne devriez pas avoir de problèmes au moment de la sortie ... arrête les ordures, les ordures.
Ce qui précède supprimera TOUTES les balises HTML et de script. Si vous avez besoin d'une solution qui autorise les balises sûres, basée sur une liste blanche, consultez HTML Purifier .
Si votre base de données est déjà empoisonnée ou si vous souhaitez gérer XSS au moment de la sortie, OWASP recommande de créer une fonction d'encapsuleur personnalisée pour
echo
, et de l'utiliser PARTOUT où vous produisez des valeurs fournies par l'utilisateur:la source
Vous pouvez également définir certains en-têtes de réponse HTTP liés à XSS via
header(...)
pour être sûr, le mode de protection XSS du navigateur est activé.
pour activer la sécurité du contenu côté navigateur. Voir celui-ci pour plus de détails sur la politique de sécurité du contenu (CSP): http://content-security-policy.com/ La configuration de CSP pour bloquer les scripts en ligne et les sources de script externes est particulièrement utile contre XSS.
pour un ensemble général d'en-têtes de réponse HTTP utiles concernant la sécurité de votre webapp, consultez OWASP: https://www.owasp.org/index.php/List_of_useful_HTTP_headers
la source
la source
preg_replace
comme il utiliseeval
sur votre entrée. owasp.org/index.php/PHP_Security_Cheat_Sheet#Code_InjectionUtiliser
htmlspecialchars
surPHP
. Sur HTML, essayez d'éviter d'utiliser:element.innerHTML = “…”; element.outerHTML = “…”; document.write(…); document.writeln(…);
où
var
est contrôlé par l'utilisateur .Évitez également évidemment d'éviter
eval(var)
, si vous devez utiliser l'un d'entre eux, essayez de les échapper JS , HTML les échapper et vous devrez peut-être en faire plus, mais pour les bases, cela devrait suffire.la source
La meilleure façon de protéger votre entrée est sa
htmlentities
fonction d' utilisation . Exemple:Vous pouvez obtenir plus d'informations ici .
la source