2

将值传递给 Sybase 查询时,在 Perl 中避免 SQL 注入的最佳方法是什么?

我担心连接到 Sybase 的 Perl 代码中的“Bobby 表”SQL 注入问题。

显然,做这样的事情:

 my $var = $ARGV[3]; # Example! I use Getopt for real
 my $sql = "select * from table1 where key1='$var'";
 $sth = $dbh->prepare($sql);
 $sth->execute();

...非常糟糕,因为用户可能会1'\ngo\ndrop table important_table\ngo'在命令行上将代码作为参数值传递。

我知道 2 个解决方案,都不好:

  • 使用去掉所有单引号s/'//g;

    这对现实生活不利,因为有时用户可能合法地想要传递包含撇号(例如姓氏)的字符串。

  • 编写一个复杂的正则表达式来检测可能的 SQL 注入

    从我的几次尝试中,这似乎几乎不可能正确。

最佳做法是什么?

4

2 回答 2

4

避免 SQL 注入的最好方法是?在 sql 查询中对输入值使用占位符,

my $sql = 'select * from table1 where key1 = ?';
$sth = $dbh->prepare($sql);
$sth->execute($var);

作为一个积极的副作用,您可以将准备好的语句用于重复$sth->execute,这对于大量插入或行更新很有用。

于 2013-06-13T22:23:33.547 回答
1

有3种方法:

  • 查找为您执行 SQL 注入检测的 CPAN 库。我读过关于SQL::Abstract.

  • 利用quote_identifier

  • 使用参数绑定(在 Perl 中不常见,但通常在从 Java 等进行 JDBC 访问时使用)。

    这很容易:

    my $var = $ARGV[3]; # Copying your example
    my $sql = "select * from table1 where key1=?";
    my $sth = $dbh->prepare($sql); # You forgot 'my' in your code!
    $sth->bind_param( 1, $var ); # 1 is the first instance of "?" in query.
    $sth->execute();
    

现在,DBI 将$var 的值绑定到第一个“?”的查询中。是。

一个很好的阅读材料是 Randal Schwartz 的文章

于 2013-06-13T22:21:31.157 回答