避免SQL注入有很多方法如何防止PHP中的SQL注入?
问题是,怎么可能通过removeBadCharacters
进行sql-inject呢?
function removeBadCharacters($s)
{
return str_replace(array('&','<','>','/','''','"',"'",'?','+'), '', $s);
}
它试图抛出危险字符(应用程序不需要这些字符):
$x = removeBadCharacters($_POST['data']);
mysql_query("insert into table (x) values ('".$x."');");
// or
mysql_query("select * from into where name = '".$x."';");
为了能够从字符串文本的上下文中注入任意SQL,需要保留该字符串文本。这只能通过引入字符串结束分隔符来实现,在这种情况下是单个'
,或者通过将字符串字元扩展到前面的'
,例如,通过使用转义字符'
:
$a = '''';
$b = ' OR 1=1 OR ';
$c = ' --';
$query = "SELECT * FROM t1 WHERE a='$a' AND b='$b' AND c='$c'";
// result:
// SELECT * FROM t1 WHERE a=''' AND b=' OR 1=1 OR ' AND c=' --'
// '_________/ '_______/
现在,当您的函数删除任何'
和'
时,似乎不可能离开或扩展字符串文字,因此不可能注入任意SQL。
然而,由于你的函数没有考虑实际的字符编码,如果MySQL的字符编码是GBK,就有可能利用这一点,类似于使用addslashes
而不是mysql_real_escape_string
时的利用方式:
$a = "'xbf";
$b = " OR 1=1 OR ";
$c = " --";
$query = "SELECT * FROM t1 WHERE a='$a' AND b='$b' AND c='$c'";
// result:
// SELECT * FROM t1 WHERE a='縗 AND b=' OR 1=1 OR ' AND c=' --'
// '_________/ '_______/
所以为了安全起见,请使用mysql_real_escape_string
或其他经过验证的方法来防止SQL注入。
删除任何字符的想法是完全错误的。
这就是你的方法本质上错误的地方。
你必须正确格式化你的SQL文字而不是破坏它们。
想象一下这个网站使用了这样的"保护":你就不能发表你的问题了!
从字面上回答你的问题-是的,在某些情况下很容易注射。仅仅因为,一次性处理的想法就被打破了。 PHP曾经有一个类似的特性,叫做"魔引号"。这是一个艰难的教训,但现在它终于从语言中删除了。因为我告诉过你的原因:
- 不生成"data"secure"
- 它反而破坏了你的数据
是的,这可以通过使用Unicode字符和操作字符集来解决。
你的函数不能处理不同的编码
不要试图自己想出卫生方法,使用已经做好的东西。在mysql_*
的情况下,它将是mysql_real_escape_string
,然而,你不应该再使用mysql_*
,使用PDO或mysqli代替。
参见:如何在PHP中防止SQL注入?