8

避免 SQL 注入有很多方法如何防止 PHP 中的 SQL 注入?.

问题是,如何通过 sql-inject 进行注入removeBadCharacters

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."';"); 
4

4 回答 4

9

为了能够从字符串文字的上下文中注入任意 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=' --'
//                          \_________/           \_______/

现在,当您的函数删除任何'and\时,似乎不可能离开或扩展字符串文字,因此无法注入任意 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 注入

于 2013-06-01T14:36:53.227 回答
5

删除任何字符的想法是完全错误的。

这就是你的方法本质上错误的地方。

您必须正确格式化 SQL 文字,而不是破坏它们。

想象一下这个网站正在使用这样的“保护”:您无法发布您的问题!

从字面上回答您的问题-是的,在某些情况下很容易注入。仅仅因为一次性消毒的想法被打破了。PHP 曾经有一个类似的功能,称为“魔术引号”。这是一个艰难的教训,但现在它终于从语言中删除了。因为我告诉你的原因:

  • 它不会使“数据”“安全”
  • 它会破坏您的数据

每个 SQL 文字都必须根据其角色单独对待。

于 2013-06-01T13:16:29.077 回答
2

您的函数不处理不同的编码。

不要试图自己想出卫生方法,使用已经制作好的东西。在 的情况下mysql_*,它将是mysql_real_escape_string,但是,您不应该再使用mysql_*,而是使用 PDO 或 mysqli。

请参阅:如何防止 PHP 中的 SQL 注入?了解更多详情。

于 2013-06-01T13:13:07.770 回答
2

是的,这可以通过使用 Unicode 字符和操作字符集来解决。

有关详细信息,请参阅https://security.stackexchange.com/questions/11391/how-did-anonymous-use-utf-16-ascii-to-fool-php-escaping

于 2013-06-01T13:13:08.870 回答