2009-08-26 2 views
36

Qualcuno sa di una buona funzione là fuori per filtrare input generici dai moduli? Zend_Filter_input sembra richiedere una conoscenza preliminare del contenuto dell'input e sono preoccupato che l'utilizzo di qualcosa come HTML Purifier avrà un grande impatto sulle prestazioni.Funzione di filtro XSS in PHP

Che dire qualcosa come: http://snipplr.com/view/1848/php--sacar-xss/

Molte grazie per qualsiasi input.

+2

HTMLPUrifier potrebbe richiedere alcune risorse, ma probabilmente non hai postato tanto contenuto? (rispetto a ciò che viene consultato, ad esempio) ;; se esegui HTMLPurifier quando salvi i dati nel DB, e non quando lo leggi dal DB, potrebbe essere OK ... –

risposta

69

Modo semplice? Utilizzare :

$str = strip_tags($input); 

È inoltre possibile utilizzare filter_var() per questo:

$str = filter_var($input, FILTER_SANITIZE_STRING); 

Il vantaggio di filter_var() è che si può controllare il comportamento, ad esempio, la decolorazione o la codifica dei caratteri basse e alte.

Ecco un elenco di sanitizing filters.

+3

grazie - non sapevo su filter_var() – codecowboy

+0

Quindi questo è il modo migliore o è purificatore HTML il modo migliore per andare per la massima sicurezza. – andho

+13

Mentre il cleto tende generalmente ad essere azzeccato, l'uso di plain old 'strip_tags()' è un enorme svista e un problema di sicurezza. Si prega di leggere quanto segue per i dettagli http://htmlpurifier.org/comparison#striptags –

23

Esistono diversi modi con cui gli hacker possono utilizzare gli attacchi XSS, le funzioni integrate di PHP non rispondono a tutti i tipi di attacchi XSS. Quindi, funzioni come strip_tags, filter_var, mysql_real_escape_string, htmlentities, htmlspecialchars, ecc non ci proteggono al 100%. Hai bisogno di un meccanismo migliore, ecco cos'è la soluzione:

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

Ehi @Sarfraz è la tua funzione davvero sicura? – Yakup

+0

dovresti anche aggiungere * urldecode * davanti a couse questo script non funziona per esempio su% 22% 3E% 3Cscript% 3Ealert ('try_xss');% 3C/script% 3E –

+1

C'è un aggiornamento a questo codice fornito di Christian Stocker: http://blog.liip.ch/archive/2008/09/10/missed-case-in-externalinput-php-resulting-in-viable-xss-attacks.html –

7

il modo migliore e sicuro è utilizzare il purificatore HTML. Segui questo link per alcuni suggerimenti su come utilizzarlo con Zend Framework.

HTML Purifier with Zend Framework

+7

Ma dammmmn è quella libreria gonfia . –

+0

Potrebbe essere gonfio, ma quando hai davvero bisogno dell'opzione nucleare per filtrarlo, è il migliore. – LaXDragon

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

non funziona. ma '$ data = filter_var ($ _ GET ['data'], FILTER_SANITIZE_STRING);' funziona. –

0

Secondo www.mcafeesecure.com soluzione generale per vulnerabile a cross-site scripting funzione di filtro (XSS) può essere:

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 risposta precedentemente accettata e con una buona spinta verso l'alto fornisce una soluzione pulita e breve. Cosa aggiunge la tua anima alla risposta? Controlla questa [metaSO question] (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) e [Jon Skeet: Coding Blog] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) su come dare una risposta corretta. – Yaroslav

3

Ho un problema simile. Ho bisogno agli utenti di inviare contenuti html in una pagina di profilo con una grande editor WYSIWYG (! Redactorjs), ho scritto la seguente funzione per ripulire il codice HTML presentata:

<?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()); } ?> 

Il $ array di controllo contiene tutti gli attributi permessi e convalida regole. Forse questo è utile per alcuni di voi. Non ho ancora testato è ancora, quindi punte sono i benvenuti

0

provare a utilizzare per Clean XSS

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

htmlspecialchars() è perfettamente adeguata per l'input dell'utente filtraggio che viene visualizzato in moduli HTML.

-1

ho trovato una soluzione per il mio problema con i messaggi con dieresi tedesco.Per fornire da totalmente pulizia (uccidendo) i pali, i codificare i dati in entrata:

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

E alla fine i decodificare l'uscita per ottenere indicazioni corrette:

*$data = utf8_decode($data);* 

Ora il palo passare attraverso il filtro funzione e ottengo un risultato corretto ...