如何使用Perl的DBI防止SQL注入攻击?

csk*_*wrd 40 mysql perl input-sanitization

在将它放入MySQL数据库之前,我是否可以使用Perl来清理输入?我不太了解正则表达式,所以在我自己完成功能之前,我想知道是否已经制作了一个.

fri*_*edo 66

清理数据以插入数据库的正确方法是使用占位符将所有变量插入到SQL字符串中.换句话说,永远不要这样做:

my $sql = "INSERT INTO foo (bar, baz) VALUES ( $bar, $baz )";
Run Code Online (Sandbox Code Playgroud)

相反,使用?占位符:

my $sql = "INSERT INTO foo (bar, baz) VALUES ( ?, ? )";
Run Code Online (Sandbox Code Playgroud)

然后在执行查询时传递要替换的变量:

my $sth = $dbh->prepare( $sql );
$sth->execute( $bar, $baz );
Run Code Online (Sandbox Code Playgroud)

您可以将这些操作与一些DBI便捷方法结合起来; 以上也可以写成:

$dbh->do( $sql, undef, $bar, $baz );
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅DBI文档.


Dav*_*man 20

"使用占位符"答案的次要(并且公认为迂腐)附录:严格来说,参数化查询不是"消毒".他们不会以任何方式修改数据以确保安全.相反,它们通过单独的通道发送查询结构(命令)和数据来防止SQL注入.

我觉得这种区别很重要的原因是因为处理消毒/引用/转义数据并使用参数化查询同样的事情意味着它们是可互换的,或者充其量,参数只是引用危险字符的更好方法,所以它是没有什么大不了的,如果你坚持引用而不是费心去找出占位符的东西.

事实上,它们是完全不同的技术,具有完全不同的可靠性水平.引用可以提供出色的防注射保护,但是确定的攻击者总是有可能找到一些会破坏或滑过引用算法并允许它们执行成功的SQL注入的极端情况.另一方面,参数化查询提供了针对SQL注入的绝对保护.由于命令和数据是分开发送的,因此无法将数据库引擎欺骗为作为命令执行数据.

除非您的语言或数据库引擎不允许您在查询中使用参数,否则请不要引用/转义/清理用户输入以防止SQL注入. 如果能够这样做,请始终使用参数化查询.

强制性链接:http: //bobby-tables.com/提供了如何在几种不同语言中使用参数化查询的示例,包括Perl.

  • +1很好的解释:当人们来寻找`mysql_real_escape_string()`时,我们知道他们有SQL注入,但完全充实的解释是很好的.(顺便说,在那里`mysql_fake_escape_string()`和`mysql_not_this_one_either_escape_string(),以及?) (2认同)

cod*_*lic 8

极少数情况下,您无法使用占位符,如其他答案中所述.但即使在极少数情况下,您也不应该自己篡改数据,因为它会为潜在的错误提供一席之地.最好使用DBI quotequote_identifier方法.它还使您的代码更少依赖于特定的RDBMS.

免责声明.以下是一个虚拟的例子,并不是为了说明我提到的非常罕见的情况.

$dbh->do('INSERT INTO ' . $dbh->quote_identifier($table) . ' (id, name) VALUES '
    '(NULL, ' . $dbh->quote($name) . ')');
Run Code Online (Sandbox Code Playgroud)

  • 你弄错了.占位符总是没问题的.我使用`quote`和`quote_identifier`来比较自己篡改数据,因为各种RDBMS有不同的引号字符. (2认同)

Mik*_*l S 7

你怎么称呼数据库?

DBI支持使用占位符的准备语句.无论DBIx ::类玫瑰:: DB ::对象自动消毒值,如果您使用的每个库提供的"发现"的方法.