2009-08-26 34 views
36

Có ai biết chức năng tốt ở đó để lọc đầu vào chung từ biểu mẫu không? Zend_Filter_input dường như yêu cầu kiến ​​thức trước về nội dung của đầu vào và tôi lo ngại rằng việc sử dụng một cái gì đó như Trình lọc HTML sẽ có tác động hiệu suất lớn.Chức năng lọc XSS trong PHP

gì về cái gì đó như: http://snipplr.com/view/1848/php--sacar-xss/

Rất cám ơn cho bất kỳ đầu vào.

+2

HTMLPUrifier có thể mất một số tài nguyên, nhưng có thể bạn không có nhiều nội dung được đăng? (so với những gì được tư vấn, ví dụ) ;; nếu bạn chạy HTMLPurifier khi lưu dữ liệu vào DB, và không phải khi đọc nó từ DB, nó có thể là ... –

Trả lời

69

Cách đơn giản? Sử dụng :

$str = strip_tags($input); 

Bạn cũng có thể sử dụng filter_var() cho rằng:

$str = filter_var($input, FILTER_SANITIZE_STRING); 

Ưu điểm của filter_var() là bạn có thể kiểm soát hành vi bằng cách, ví dụ, tước hoặc mã hóa ký tự thấp và cao.

Dưới đây là danh sách sanitizing filters.

+3

cảm ơn - không biết về filter_var() – codecowboy

+0

Vì vậy, đây là cách tốt nhất hay là Trình lọc HTML cách tốt nhất để bảo mật tối đa. – andho

+13

Trong khi cletus thường có khuynh hướng được phát hiện, sử dụng 'strip_tags()' cũ là một sự giám sát rất lớn và một mối quan tâm về bảo mật. Vui lòng đọc phần sau để biết chi tiết http://htmlpurifier.org/comparison#striptags –

23

Có một số cách thức mà tin tặc được đưa vào sử dụng cho các cuộc tấn công XSS, các hàm dựng sẵn của PHP không phản hồi tất cả các loại tấn công XSS. Do đó, các chức năng như strip_tags, filter_var, mysql_real_escape_string, htmlentities, htmlspecialchars, vv không bảo vệ chúng ta 100%. Bạn cần một cơ chế tốt hơn, đây là giải pháp là gì:

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 là chức năng của bạn thực sự an toàn? – Yakup

+0

bạn cũng nên thêm * urldecode * vào trước couse tập lệnh này không hoạt động, ví dụ:% 22% 3E% 3Cscript% 3Ealert ('try_xss');% 3C/script% 3E –

+1

Có bản cập nhật cho mã này được cung cấp bởi Christian Stocker: http://blog.liip.ch/archive/2008/09/10/missed-case-in-externalinput-php-resulting-in-viable-xss-attacks.html –

7

cách tốt nhất và an toàn là sử dụng Trình lọc HTML. Theo liên kết này để biết một số gợi ý về cách sử dụng nó với Zend Framework.

HTML Purifier with Zend Framework

+7

Nhưng dammmmn là thư viện cồng kềnh . –

+0

Nó có thể cồng kềnh, nhưng khi bạn thực sự cần tùy chọn hạt nhân để lọc nó ra, nó là tốt nhất. – LaXDragon

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

không hoạt động. nhưng '$ data = filter_var ($ _ GET ['dữ liệu'], FILTER_SANITIZE_STRING);' hoạt động. –

0

Theo www.mcafeesecure.com Giải pháp chung cho dễ bị cross-site scripting (XSS) chức năng lọc có thể là:

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

Câu trả lời được chấp nhận trước đây và được trả lời rất cao cung cấp giải pháp sạch và ngắn. Linh hồn của bạn thêm vào câu trả lời đó là gì? Kiểm tra [câu hỏi metaSO] này (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) và [Jon Skeet: Blog mã hóa] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) về cách đưa ra câu trả lời đúng. – Yaroslav

3

Tôi có một vấn đề tương tự. Tôi cần người sử dụng gửi nội dung html đến một trang hồ sơ cá nhân với một trình soạn thảo WYSIWYG lớn (! Redactorjs), tôi đã viết các chức năng sau đây để làm sạch html nộp:

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

Các $ séc mảng chứa tất cả các thuộc tính cho phép và xác nhận quy tắc. Có lẽ điều này rất hữu ích cho một số bạn. Tôi đã không kiểm tra là chưa, vì vậy lời khuyên được hoan nghênh

0

Cố gắng sử dụng cho sạch XSS

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

htmlspecialchars() là hoàn toàn phù hợp cho người dùng lọc đầu vào sẽ được hiển thị ở dạng html.

-1

Tôi tìm thấy một giải pháp cho vấn đề của tôi với bài viết với âm sắc Đức.Để cung cấp từ hoàn toàn sạch (giết chết) các bài viết, tôi mã hóa dữ liệu đến:

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

Và cuối cùng tôi giải mã đầu ra để có được dấu hiệu chính xác:

*$data = utf8_decode($data);* 

Bây giờ bài đi qua bộ lọc chức năng và tôi nhận được kết quả chính xác ...