311 votes

Comment prévenir les XSS avec HTML/PHP ?

Comment éviter les XSS (cross-site scripting) en utilisant uniquement HTML et PHP ?

J'ai vu de nombreux autres articles sur ce sujet, mais je n'en ai pas trouvé un qui explique de manière claire et concise comment prévenir les XSS.

3 votes

Notez que cela ne résoudra pas le cas où vous souhaiteriez utiliser les données de l'utilisateur comme attribut HTML. Par exemple, l'URL source d'une image. Ce n'est pas un cas courant, mais il est facile de l'oublier.

0 votes

@MichaelMior voici une solution pour empêcher les XSS dans href o src Attribut HTML : stackoverflow.com/questions/19047119/

0 votes

Il y a un bon article aquí qui explique le XSS et comment l'éviter dans différents langages (dont le PHP).

12voto

Scott Points 389

Par ordre de préférence :

  1. Si vous utilisez un moteur de création de modèles (par exemple Twig, Smarty, Blade), vérifiez qu'il offre un échappement sensible au contexte. Je sais par expérience que Twig le fait. {{ var|e('html_attr') }}
  2. Si vous voulez autoriser le HTML, utilisez Purificateur HTML . Même si vous pensez que vous n'acceptez que Markdown ou ReStructuredText, vous devez purifier le HTML que ces langages de balisage produisent.
  3. 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' est le jeu de caractères souhaité.

En outre, assurez-vous que vous échapper à la sortie, pas à l'entrée .

3voto

Abdo Host Points 9
<?php
function xss_clean($data)
{
// Fix &entity\n;
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');

// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);

// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);

// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);

// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);

do
{
    // Remove really unwanted tags
    $old_data = $data;
    $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);

// we are done...
return $data;
}

3voto

chris Points 24

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 cette page pour plus de détails sur la politique de sécurité du contenu (CSP) : http://content-security-policy.com/ La mise en place de CSP pour bloquer les scripts en ligne et les sources externes de script est particulièrement utile contre les XSS.

Pour un ensemble d'en-têtes de réponse HTTP utiles concernant la sécurité de votre application Web, consultez le site de l'OWASP : https://www.owasp.org/index.php/List_of_useful_HTTP_headers

3voto

Tom Schlick Points 1897

Jetez un coup d'œil à la série "Writing Secure" sur AddedBytes.com.

http://www.addedbytes.com/writing-secure-php/

il y a beaucoup plus de choses à faire pour écrire un code php sécurisé que juste htmlspecialchars, parce que cela ne protège pas contre les injections sql ou quelque chose comme ça.

-1voto

Pablo Points 9

Utilisez htmlspecialchars en PHP . En HTML, essayez d'éviter d'utiliser :

element.innerHTML = “…”; element.outerHTML = “…”; document.write(…); document.writeln(…);

donde var es contrôlé par l'utilisateur .

Essayez aussi d'éviter eval(var) , si vous devez utiliser l'un d'entre eux, essayez alors JS en leur échappant, HTML échappez-les et vous devrez peut-être en faire d'autres, mais pour l'essentiel, cela devrait suffire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X