1.XSS漏洞修復
從上面XSS實例以及之前文章的介紹我們知道XSS漏洞的起因就是沒有對用戶提交的數據進行嚴格的過濾處理。因此在思考解決XSS漏洞的時候,我們應該重點把握如何才能更好的將用戶提交的數據進行安全過濾。
html實體
什么是html實體?
在html中有些字符,像(<)這類的,對HTML(標准通用標記語言下的一個應用)來說是有特殊意義的,所以這些字符是不允許在文本中使用的。要在HTML中顯示(<)這個字符,我們就必須使用實體字符。
html實體的存在是導致XSS漏洞的主要原因之一。
因此我們需要將這些實體全部轉換為相應的實體編號。
|
顯示結果
|
描述
|
實體名稱
|
|
|
空格
|
|
|
<
|
小於號
|
<
|
|
>
|
大於號
|
>
|
|
&
|
和號
|
&
|
|
"
|
引號
|
"
|
|
'
|
撇號
|
' (IE不支持)
|
HTML Encode
用戶將數據提交上來的時候進行HTML編碼,將相應的符號轉換為實體名稱再進行下一步的處理。
在PHP中已經存在這樣子功能的函數,即是htmlentities($str)函數。
與之相反的就是html_entity_decode($str)函數,它將實體名稱轉換為相應的符號。
修復漏洞方針
【不相應用戶提交的數據,過濾過濾過濾!】
1、將重要的cookie標記為http only, 這樣的話Javascript 中的document.cookie語句就不能獲取到 cookie了.
2、表單數據規定值的類型,例如:年齡應為只能為int、name只能為字母數字組合。。。。
4、對數據進行Html Encode 處理
5、過濾或移除特殊的Html標簽, 例如: <script>, <iframe> , < for <, > for >, " for
6、過濾JavaScript 事件的標簽。例如 "onclick=", "onfocus" 等等。
【特別注意:】
在有些應用中是允許html標簽出現的,甚至是javascript代碼出現。因此我們在過濾數據的時候需要仔細分析哪些數據是有特殊要求(例如輸出需要html代碼、javascript代碼拼接、或者此表單直接允許使用等等),然后區別處理!
PHP中的相應函數
【詳細看PHP手冊】
這里可能不全,想了解更多的看手冊
|
strip_tags($str, [允許標簽])
|
從字符串中去除 HTML 和 PHP 標記
|
|
htmlentities($str)
|
轉義html實體
|
|
html_entity_decode($str)
|
反轉義html實體
|
|
addcslashes($str, ‘字符’)
|
給某些字符加上反斜杠
|
|
stripcslashes($str)
|
去掉反斜杠
|
|
addslashes ($str )
|
單引號、雙引號、反斜線與 NULL加反斜杠
|
|
stripslashes($str)
|
去掉反斜杠
|
|
htmlspecialchars()
|
特殊字符轉換為HTML實體
|
|
htmlspecialchars_decode()
|
將特殊的 HTML 實體轉換回普通字符
|
數據過濾類
<?php class XSS { /** * @desc 過濾數據 * * @param $data string|array 輸入數據 * @param $low bool 是否采用更為嚴格的過濾 * * @return 返回過濾的數據 */
public function clean_xss($data, $low = False) { #字符串過濾 if (! is_array ( $data )) { $data = trim ( $data ); #字符兩邊的處理 $data = strip_tags ( $data ); #從字符串中去除 HTML 和 PHP 標記 $data = htmlspecialchars ( $data ); #特殊字符轉換為HTML實體 if ($low) { return $data; } #匹配換空格 $data = str_replace ( array ('"', "\\", "'", "/", "..", "../", "./", "//" ), '', $data ); $no = '/%0[0-8bcef]/'; $data = preg_replace ( $no, '', $data ); $no = '/%1[0-9a-f]/'; $data = preg_replace ( $no, '', $data ); $no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; $data = preg_replace ( $no, '', $data ); return $data; } #數組過濾 $arr=array(); foreach ($data as $k => $v) { $temp=$this->clean_xss($v); $arr[$k]=$temp; } return $arr; } } #測試測試 session_start(); $_SESSION['xss']='xssss'; $xss=new XSS(); #測試字符串 $str = "<script>alert(document.cookie)</script>"; echo $str; $str2=$xss->clean_xss($str); echo $str2; echo "<hr/>"; #測試數組 $arr=array("<script>alert(document.cookie)</script>","<script>alert(document.cookie)</script>","<script>alert(document.cookie)</script>"); echo "<pre>"; print_r($arr); echo "</pre>"; $arr2=$xss->clean_xss($arr); echo "<pre>"; print_r($arr2); echo "</pre>";die; ?>
