如一些银行卡号,身份证号,邮箱,电话号码,,生日,邮政编码等这些有自己规定的格式且格式规定不能有空格符号的参数,在过滤的时候一般最先过滤掉空格(包括一些空格“变种”),因为其他字符界定符号,逻辑关键字,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