如一些銀行卡號,身份證號,郵箱,電話號碼,,生日,郵政編碼等這些有自己規定的格式且格式規定不能有空格符號的參數,在過濾的時候一般最先過濾掉空格(包括一些空格“變種”),因為其他字符界定符號,邏輯關鍵字,mysql注悉,注意下圖可以看出重要的是“'”,“ ”
ps:空格字符的變種有:“%20”,“\n”,“\r”,“\r\n”,“\n\r”,“chr("32")” 這也是為什么mysql_escape_string()和mysql_real_escape_string() 兩個函數轉義“\n”,“\r”。其實很多phper只知道轉義\n,\r而不知原因,在mysql解析\n,\r時把它們當成空格處理,筆者測試驗證過,這里就不貼代碼了。
(2)“and”,“or”,“\”,“#”,“-- ”
邏輯關鍵可以組合很多注入代碼;mysql注悉則把固有sql代碼后面的字符全部給注悉掉從而讓注入后的sql語句能正常運行;“\”也是能組合很多注入字符\x00,\x1a。
ps:sql 解析“#”,“-- ”是大多數mysql防注入代碼沒有考慮到的,也是很多phper忽略。還有因為一些phper給參數賦值的時候會有用“-”來隔開,所以筆者建議不要這樣寫參數,當然也可以再過濾參數的時候“-- ”(注意有空格的,沒空格不解析為注悉)當一個整體過濾而不是過濾“-” ,這樣就避免過多過濾參數。
(3)“null”,“%”,“_”
這幾個不能獨立,都不要在特定情況下,比如通配字符“%,_”都要在mysql like子句的前提下。所以“%”,“_”的過濾一般在搜索相關才過濾,不能把它們納入通常過濾隊列,因為有些如郵箱就可以有”_”字符
(4)關鍵字“select|insert|update|delete|*|union|join|into|load_file|outfile”
也許你會問怎么這些重要關鍵字卻優先級這么低。筆者想說的是因為這些關鍵字在沒有“'”,“"”,“”,“and”,“or”等情況下購不成傷害。換句話說這些關鍵字不夠“獨立”,“依賴性”特別大。當然優先級低,不代表不要過濾。
3.3.3防注入代碼。
(1)參數是數字直接用intval()函數
注意:現在很多網上流行的防注入代碼都只是只是用addslashes()、mysql_escape_string()、mysql_real_escape_string()或三者任意組合過濾,但phper以為過濾了,一不小心一樣有漏洞,那就是在參數為數字的時候:
$id = addslashes($_POST['id']); //正確是$id = intval($_POST['id']);
$sql =" select * from phpben.com where id =$id";
$sql =" select * from phpben.com where id =1 or 1=1";
對比容易發現,post過來的數據通過addslashes過濾后的確很多注入已經不起作用,但是$id并沒有intval,導致漏洞的存在,這是個小細節,不小心則導致漏洞。
(2)對于非文本參數的過濾
文本參數是指標題、留言、內容等可能有“’”,“’”等內容,過濾時不可能全部轉義或代替。
但非文本數據可以。
function _str_replace($str )
{
$str = str_replace(" ","",$str);
$str = str_replace("\n","",$str);
$str = str_replace("\r","",$str);
$str = str_replace("'","",$str);
$str = str_replace('"',"",$str);
$str = str_replace("or","",$str);
$str = str_replace("and","",$str);
$str = str_replace("#","",$str);
$str = str_replace("\\","",$str);
$str = str_replace("-- ","",$str);
$str = str_replace("null","",$str);
$str = str_replace("%","",$str);
//$str = str_replace("_","",$str);
$str = str_replace(">","",$str);
$str = str_replace("<","",$str);
$str = str_replace("=","",$str);
$str = str_replace("char","",$str);
$str = str_replace("declare","",$str);
$str = str_replace("select","",$str);
$str = str_replace("create","",$str);
$str = str_replace("delete","",$str);
$str = str_replace("insert","",$str);
$str = str_replace("execute","",$str);
$str = str_replace("update","",$str);
$str = str_replace("count","",$str);
return$str;
}
ps:
還有一些從列表頁操作過來的一般href是”phpben.php?action=delete&id=1”,這時候就注意啦,_str_replace($_GET['action'])會把參數過濾掉,筆者一般不用敏感關鍵作為參數,比如delete會寫成 del,update寫成edite,只要不影響可讀性即可;
原文轉自:http://blogread.cn/it/article/6086