2009-08-26 5 views
36

Est-ce que quelqu'un connaît une bonne fonction pour filtrer les entrées génériques des formulaires? Zend_Filter_input semble nécessiter une connaissance préalable du contenu de l'entrée et je crains que l'utilisation de quelque chose comme HTML Purifier ait un impact important sur les performances.Fonction de filtrage XSS en PHP

Qu'en est-il quelque chose comme: http://snipplr.com/view/1848/php--sacar-xss/

Un grand merci pour toute entrée.

+2

HTMLPUrifier peut prendre quelques ressources, mais vous n'avez probablement pas beaucoup de contenu posté? (comparé à ce qui est consulté, par exemple); Si vous exécutez HTMLPurifier lors de l'enregistrement des données dans la base de données, et non lors de la lecture de la base de données, cela pourrait être OK ... –

Répondre

69

Simple façon? Utilisez :

$str = strip_tags($input); 

Vous pouvez également utiliser filter_var() pour que:

$str = filter_var($input, FILTER_SANITIZE_STRING); 

L'avantage de filter_var() est que vous pouvez contrôler le comportement, par exemple, le décapage ou l'encodage des caractères faibles et élevés.

Voici une liste de sanitizing filters.

+3

merci - ne savait pas à propos de filter_var() – codecowboy

+0

Donc, est-ce la meilleure façon? le meilleur moyen d'aller pour une sécurité maximale. – andho

+13

Alors que le cletus a tendance à être sur place, utiliser old 'strip_tags()' est un énorme oubli et un problème de sécurité. S'il vous plaît lire ce qui suit pour plus de détails http://htmlpurifier.org/comparison#striptags –

23

Il y a un certain nombre de façons dont les pirates informatiques utilisent les attaques XSS, les fonctions intégrées de PHP ne répondent pas à toutes sortes d'attaques XSS. Par conséquent, les fonctions telles que strip_tags, filter_var, mysql_real_escape_string, htmlentities, htmlspecialchars, etc. ne nous protègent pas à 100%. Vous avez besoin d'un meilleur mécanisme, voici ce qui est la solution:

function xss_clean($data) 
{ 
// Fix &entity\n; 
$data = str_replace(array('&','<','>'), array('&','<','>'), $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; 
} 
+3

Hey @Sarfraz est votre fonction vraiment sécuritaire? – Yakup

+0

vous devriez aussi ajouter * urldecode * devant couse ce script ne fonctionne pas par exemple sur% 22% 3E% 3Cscript% 3Ealert ('try_xss');% 3C/script% 3E –

+1

Il y a une mise à jour de ce code fourni par Christian Stocker: http://blog.liip.ch/archive/2008/09/10/missed-case-in-externalinput-php-resulting-in-viable-xss-attacks.html –

7

le meilleur et le moyen sécurisé est d'utiliser HTML Purifier. Suivez ce lien pour quelques conseils sur l'utilisation de Zend Framework.

HTML Purifier with Zend Framework

+7

Mais dammmmn est cette bibliothèque gonflée . –

+0

Il peut être gonflé, mais quand vous avez vraiment besoin de l'option nucléaire pour le filtrer, c'est le meilleur. – LaXDragon

2
function clean($data){ 
    $data = rawurldecode($data); 
    return filter_var($data, FILTER_SANITIZE_SPEC_CHARS); 
} 
+1

ne fonctionne pas. mais '$ data = filter_var ($ _ GET ['data'], FILTER_SANITIZE_STRING);' fonctionne. –

0

Selon www.mcafeesecure.com solution générale pour vulnérable aux cross-site scripting (XSS) fonction de filtre peut être:

function xss_cleaner($input_str) { 
    $return_str = str_replace(array('<','>',"'",'"',')','('), array('&lt;','&gt;','&apos;','&#x22;','&#x29;','&#x28;'), $input_str); 
    $return_str = str_ireplace('%3Cscript', '', $return_str); 
    return $return_str; 
} 
+0

La réponse précédemment acceptée et fortement mise à jour fournit une solution propre et courte. Qu'est-ce que votre soulution ajoute à cette réponse? Cochez cette [question metaSO] (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) et [Jon Skeet: Coding Blog] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) sur comment donner une réponse correcte. – Yaroslav

3

J'ai un problème similaire. Je dois aux utilisateurs de soumettre du contenu HTML sur une page de profil avec un éditeur WYSIWYG (! Redactorjs), je l'ai écrit la fonction suivante pour nettoyer le code html soumis:

<?php function filterxss($str) { 
//Initialize DOM: 
$dom = new DOMDocument(); 
//Load content and add UTF8 hint: 
$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">'.$str); 
//Array holds allowed attributes and validation rules: 
$check = array('src'=>'#(http://[^\s]+(?=\.(jpe?g|png|gif)))#i','href'=>'|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i'); 
//Loop all elements: 
foreach($dom->getElementsByTagName('*') as $node){ 
    for($i = $node->attributes->length -1; $i >= 0; $i--){ 
     //Get the attribute: 
     $attribute = $node->attributes->item($i); 
     //Check if attribute is allowed: 
     if(in_array($attribute->name,array_keys($check))) { 
      //Validate by regex:  
      if(!preg_match($check[$attribute->name],$attribute->value)) { 
       //No match? Remove the attribute 
       $node->removeAttributeNode($attribute); 
      } 
     }else{ 
      //Not allowed? Remove the attribute: 
      $node->removeAttributeNode($attribute); 
     } 
    } 
} 
var_dump($dom->saveHTML()); } ?> 

Le tableau de contrôle de $ contient tous les attributs autorisés et validation règles. Peut-être que cela est utile pour certains d'entre vous. Je n'ai pas testé est encore, si des conseils sont les bienvenus

0

Essayez d'utiliser pour nettoyer XSS

xss_clean($data): "><script>alert(String.fromCharCode(74,111,104,116,111,32,82,111,98,98,105,101))</script> 
1

htmlspecialchars() est parfaitement adéquate pour l'entrée utilisateur de filtrage qui est affiché sous forme html.

-1

J'ai trouvé une solution pour mon problème avec les messages avec tréma allemand.Fournir du nettoyage totalement (tuer) les postes, j'encoder les données entrantes:

*$data = utf8_encode($data); 
    ... function ...* 

Et enfin je décode la sortie pour obtenir des signes corrects:

*$data = utf8_decode($data);* 

maintenant le poste de passer par le filtre Fonction et j'obtiens un résultat correct ...