下面針對常用表單特殊字元處理進行總結:
測試字串:
代碼如下 |
複製代碼 |
$dbstr='D:test <a href="http://www.111cn.net">http://www.111cn.net</a>,天緣部落格 '!='1' OR '1' </DIV> <script language="javascript" type="text/javascript">alert("Fail");</script> <?php echo "<br/>PHP OUTPUT"; ?>';
|
測試代碼:
代碼如下 |
複製代碼 |
header("Content-Type: text/html; charset=UTF-8"); echo "------------------------------------------------------<br/>rn"; echo $dbstr."<br/>rn------------------------------------------------------<br/>rn"; $str=fnAddSlashes($_POST['dd']); echo $str."<br/>rn------------------------------------------------------<br/>rn"; $str = preg_replace("/s(?=s)/","\1",$str);//多個連續空格只保留一個 $str = str_replace("r","<br/>",$str); $str = str_replace("n","<br/>",$str); $str = preg_replace("/((<br/?>)+)/i", "<br/>", $str);//多個連續<br/>標籤只保留一個 $str=stripslashes($str); echo strip_tags($str)."<br/>rn------------------------------------------------------<br/>rn"; echo htmlspecialchars($str)."<br/>rn------------------------------------------------------<br/>rn"; echo htmlentities($str)."<br/>rn------------------------------------------------------<br/>rn"; echo mysql_escape_string($str)."<br/>rn------------------------------------------------------<br/>rn"; |
字串包含:反斜線路徑,單雙引號,HTML標記、連結、未封堵的HTML標記,資料庫文法容錯,JS執行判斷,PHP執行判斷,多個連續斷行符號分行符號和空格。其中有些概念有內含項目關聯性
二、表單提交資料處理
1、強制加入反斜線
由於有些主機預設開啟魔術引用get_magic_quotes_gpc,有些可能關閉,所以在程式上最好一律強制加入反斜線,這樣可以統一處理,字元涉及單引號、雙引號和反斜線。
代碼如下 |
複製代碼 |
function fnAddSlashes($data) { if(!get_magic_quotes_gpc()) //只對POST/GET/cookie過來的資料增加轉義 return is_array($data)?array_map('addslashes',$data):addslashes($data); else return $data; } |
2、對特殊字元處理
以下是幾個常用字串處理,可以視具體情況取捨。由於上面已經對提交表單資料進行一次轉義,所以如果需要對內容替換或過濾需要考慮addslashes對相關字元的影響,替換或尋找時需考慮反斜線的添加。其它字元替換不影響,比如rn替換。
A、多個連續空格只保留一個
代碼如下 |
複製代碼 |
$data = preg_replace("/s(?=s)/","\1",$data );//多個連續空格只保留一個 |
B、斷行符號換行替換成<br/>
代碼如下 |
複製代碼 |
$data = str_replace("r","<br/>",$data ); $data = str_replace("n","<br/>",$data ); |
//html中預設<br>沒封堵,xhtml中<br/>有封堵,建議使用<br/>,更多區別:
C、多個連續<br/>只保留一個
代碼如下 |
複製代碼 |
$data = preg_replace("/((<br/?>)+)/i", "<br/>", $data );//多個連續<br/>標籤只保留一個
|
D、全部過濾HTML標記
該方式是全部過濾潛在危險的標記,包括HTML、連結、未封堵HTML標記、JS、PHP。
使用函數strip_tags($data)
該函數使用後會過濾全部的HTML標記(包括連結)和PHP標記、JS代碼等,其中連結會保留連結原文只是去除<a>標記和href部分內容,PHP標記和JS標記則會整體去除,包括中間的內容,如下圖:
E、不過濾標記,只是把他們HTML化
該方法是把原提交內容全部按照普通文本來處理。
使用函數htmlspecialchars($data),該函數執行後會把提交資料全部按照普通文本來展示,如下圖:
使用htmlentities函數執行結果(中文顯示亂碼):
三、寫入資料庫
由於使用addslashes($data)後對於進階的可信任使用者可以直接寫入資料庫,但是addslashes無法攔截使用0xbf27代替的單引號,所以最好還是使用mysql_real_escape_string或mysql_escape_string進行轉義,不過轉義之前需先去除反斜線(假設已預設開啟addslashes)。
代碼如下 |
複製代碼 |
function fnEscapeStr($data) { if (get_magic_quotes_gpc()) { $data= stripslashes($value); } $data="'". mysql_escape_string($value) ."'"; return $data; } $data=fnEscapeStr($data); |
PHP通用防注入安全的程式碼
代碼如下 |
複製代碼 |
說明: 判斷傳遞的變數中是否含有非法字元 如$_POST、$_GET 功能: 防注入 **************************/ //要過濾的非法字元 $ArrFiltrate=array(”‘”,”;”,”union”); //出錯後要跳轉的url,不填則預設前一頁 $StrGoUrl=”"; //是否存在數組中的值 function FunStringExist($StrFiltrate,$ArrFiltrate){ foreach ($ArrFiltrate as $key=>$value){ if (eregi($value,$StrFiltrate)){ return true; } } return false; } //合并$_POST 和 $_GET if(function_exists(array_merge)){ $ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS); }else{ foreach($HTTP_POST_VARS as $key=>$value){ $ArrPostAndGet[]=$value; } foreach($HTTP_GET_VARS as $key=>$value){ $ArrPostAndGet[]=$value; } } //驗證開始 foreach($ArrPostAndGet as $key=>$value){ if (FunStringExist($value,$ArrFiltrate)){ echo “alert(/”Neeao提示,非法字元/”);”; if (empty($StrGoUrl)){ echo “history.go(-1);”; }else{ echo “window.location=/”".$StrGoUrl.”/”;”; } exit; } } ?>
|
/*************************
儲存為checkpostandget.php
然後在每個php檔案前加include(“checkpostandget.php“);即可