41

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

4

5 回答 5

67

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

my $sql = "INSERT INTO foo (bar, baz) VALUES ( $bar, $baz )";

相反,使用?占位符:

my $sql = "INSERT INTO foo (bar, baz) VALUES ( ?, ? )";

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

my $sth = $dbh->prepare( $sql );
$sth->execute( $bar, $baz );

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

$dbh->do( $sql, undef, $bar, $baz );

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

于 2010-02-20T02:28:07.870 回答
20

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

我觉得这种区别很重要的原因是因为将清理/引用/转义数据和使用参数化查询视为同一件事意味着它们是可互换的,或者充其量只是引用危险字符的更好方法,所以它是如果您坚持引用而不是费心找出占位符的东西,那没什么大不了的。

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

除非您的语言或数据库引擎不允许您在查询中使用参数,否则切勿引用/转义/清理用户输入以防止 SQL 注入。 如果可以的话,请始终为此目的使用参数化查询。

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

于 2010-02-20T10:41:46.207 回答
8

极少数情况下,您无法使用占位符,如其他答案中所述。但即使在这种罕见的情况下,您也不应该自己篡改数据,因为它为潜在的错误提供了空间。最好使用 DBIquotequote_identifier方法。它还使您的代码减少了对特定 RDBMS 的依赖。

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

$dbh->do('INSERT INTO ' . $dbh->quote_identifier($table) . ' (id, name) VALUES '
    '(NULL, ' . $dbh->quote($name) . ')');
于 2010-02-20T07:23:48.993 回答
7

你怎么称呼数据库?

DBI支持使用占位符的预准备语句。如果您使用每个库提供的“查找”方法,DBIx ::ClassRose::DB::Object都会自动清理值。

于 2010-02-20T02:23:33.543 回答
0

答案:使用 SQL 占位符 (?)。

原因:SQL语句的结构和占位符表示的数据值完全分开发送到数据库。所以绝对不可能将数据值解释为 SQL 命令。

于 2015-03-16T04:24:48.290 回答