如何使用Perl的DBI防止SQL注入攻击?
有一个函数,我可以在Perl中使用,以消毒input之前将其放入MySQL数据库? 我不知道正则expression式,所以在我做自己的函数之前,我想知道是否已经有了一个。
清理数据以插入数据库的正确方法是使用占位符将所有variables插入到SQLstring中。 换句话说,永远不要这样做:
my $sql = "INSERT INTO foo (bar, baz) VALUES ( $bar, $baz )";
反而使用?
占位符:
my $sql = "INSERT INTO foo (bar, baz) VALUES ( ?, ? )";
然后在执行查询时传递要replace的variables:
my $sth = $dbh->prepare( $sql ); $sth->execute( $bar, $baz );
您可以将这些操作与某些DBI便利方法结合使用; 以上也可以这样写:
$dbh->do( $sql, undef, $bar, $baz );
请参阅DBI文档以获取更多信息。
轻微(并且是迂腐的)“使用占位符”答案的附录:严格地说,参数化查询不是“消毒”。 他们不以任何方式修改数据以保证安全。 相反,它们通过单独的渠道发送查询结构(命令)和数据来防止SQL注入。
我觉得这个区别很重要的原因是,处理消毒/引用/转义你的数据和使用参数化查询作为同一事物意味着它们是可以互换的,或者说,参数只是引用危险字符的一种更好的方式,所以它没有什么大不了的,如果你坚持引用,而不是打扰找出占位符的东西。
事实上,他们是完全不同的技术,具有完全不同的可靠性水平。 引用可以提供很好的防止注入的保护,但是总有一个确定的攻击者可能会发现一些将通过引用algorithm中断或滑落的angular落案例,并允许他们执行成功的SQL注入。 另一方面,参数化查询为SQL注入提供了绝对的保护。 由于命令和数据是分开发送的,因此数据库引擎无法被诱骗执行数据作为命令。
除非您的语言或数据库引擎不允许您在查询中使用参数,否则请勿将用户input/ escape / sanitize作为防范SQL注入的保护措施。 如果可以,请始终使用参数化查询来实现此目的。
和必须的链接: http : //bobby-tables.com/有如何使用几种不同的语言,包括Perl的参数化查询的例子。
在极less数情况下,您无法使用占位符,如其他答案中所述。 但即使在这种罕见的情况下,您也不应该自行篡改数据,因为这会造成潜在的错误。 最好使用DBI的quote
和quote_identifier
方法。 此外,它使您的代码更less依赖于特定的RDBMS。
免责声明。 以下是一个虚拟的例子,并不是要说明我提到的非常罕见的情况 。
$dbh->do('INSERT INTO ' . $dbh->quote_identifier($table) . ' (id, name) VALUES ' '(NULL, ' . $dbh->quote($name) . ')');
你如何调用数据库?
DBI支持使用占位符的预处理语句。 如果使用每个库提供的“find”方法, DBIx :: Class和Rose :: DB :: Object都会自动清理值。
答案:使用SQL占位符(?)。
原因:SQL语句的结构和由占位符表示的数据值完全分开发送到数据库。 所以绝对没有办法将数据值解释为SQL命令。