2009-08-26 6 views
36

Czy ktoś wie o dobrej funkcji tam do filtrowania ogólnych danych wejściowych z formularzy? Wydaje się, że Zend_Filter_input wymaga wcześniejszej wiedzy o zawartości danych wejściowych i obawiam się, że użycie czegoś takiego jak HTML Purifier będzie miało duży wpływ na wydajność.Funkcja filtrowania XSS w PHP

Co o czymś takim: http://snipplr.com/view/1848/php--sacar-xss/

Dziękujemy za każdym wejściu.

+2

HTMLPUrifier może wymagać pewnych zasobów, ale prawdopodobnie nie opublikowano zbyt wielu treści? (w porównaniu do tego, na co się zwrócono, na przykład); jeśli uruchomisz narzędzie HTMLPurifier podczas zapisywania danych do DB, a nie podczas odczytu z DB, może być OK ... –

Odpowiedz

69

Prosty sposób? Użyj :

$str = strip_tags($input); 

Można również użyć do tego filter_var():

$str = filter_var($input, FILTER_SANITIZE_STRING); 

Zaletą filter_var() jest to, że można kontrolować zachowanie, na przykład usuwanie lub kodowania znaków wysokich i niskich.

Oto lista sanitizing filters.

+3

dzięki - nie wiedziałeś o filter_var() – codecowboy

+0

Czy to jest najlepszy sposób, czy jest to HTML Purifier najlepszy sposób na maksymalne bezpieczeństwo. – andho

+13

Podczas gdy clet zazwyczaj jest na miejscu, używanie zwykłego 'strip_tags()' jest ogromnym nadzorem i problemem bezpieczeństwa. Przeczytaj poniższe szczegóły: http://htmlpurifier.org/comparison#striptags –

23

Istnieje wiele sposobów użycia hakerów do ataków XSS, wbudowane funkcje PHP nie reagują na różnego rodzaju ataki XSS. W związku z tym funkcje takie jak strip_tags, filter_var, mysql_real_escape_string, htmlentities, htmlspecialchars itp. Nie chronią nas w 100%. Potrzebujesz lepszego mechanizmu, oto, czym jest rozwiązanie:

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

Hej @Sarfraz to twoja funkcja naprawdę bezpieczna? – Yakup

+0

powinieneś również dodać * urldecode * przed kursem, który nie działa na przykład na% 22% 3E% 3Cscript% 3Ealert ('try_xss');% 3C/script% 3E –

+1

Istnieje aktualizacja tego kodu pod warunkiem Christian Stocker: http://blog.liip.ch/archive/2008/09/10/missed-case-in-externalinput-php-resulting-in-viable-xss-attacks.html –

7

Najlepszym i bezpiecznym sposobem jest użycie HTML Purifier. Kliknij ten link, aby uzyskać wskazówki dotyczące korzystania z Zend Framework.

HTML Purifier with Zend Framework

+7

Ale dammmmn to ta biblioteka opuchnięta . –

+0

Może być nadęty, ale kiedy naprawdę potrzebujesz opcji nuklearnej, aby go odfiltrować, jest najlepszy. – LaXDragon

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

nie działa. ale '$ data = filter_var ($ _ GET ['data'], FILTER_SANITIZE_STRING);' działa. –

0

Według www.mcafeesecure.com ogólne rozwiązanie dla trudnej do cross-site scripting (XSS) funkcję filtra może być:

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

Przyjęta uprzednio i wysoce przegłosowana odpowiedź zapewnia czyste i krótkie rozwiązanie. Co twoja dusza dodaje do tej odpowiedzi? Sprawdź to [pytanie metaSO] (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) i [Jon Skeet: Coding Blog] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) na temat udzielania poprawnej odpowiedzi. – Yaroslav

3

mam podobny problem. Muszę użytkownikom przesyłanie treści HTML do strony profilu z wielkim edytora WYSIWYG (! Redactorjs), napisałem następującą funkcję czyszczenia przedłożone HTML: tablica check

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

$ posiada wszystkie dozwolony atrybuty i walidacji zasady. Może to jest przydatne dla niektórych z was. I nie jest jeszcze testowany, więc wskazówki są mile widziane

0

Spróbuj użyć dla Czystego XSS

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

htmlspecialchars() jest całkowicie wystarczające do filtrowania danych wejściowych użytkownika, który jest wyświetlany w postaci html.

-1

Znalazłem rozwiązanie mojego problemu ze słupkami z niemieckim umlaut.Aby dostarczyć z całkowicie czyszczenia (zabijanie) stanowiska, i kodować dane przychodzące:

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

iw końcu rozszyfrować wyjście, aby uzyskać poprawne znaki:

*$data = utf8_decode($data);* 

Teraz po przejść przez filtr funkcja i otrzymuję poprawny wynik ...