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

时间:2013-06-13 22:15:54

标签: sql perl sql-injection sybase

在将值传递给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'之类的代码作为参数值。

我知道两种解决方案,都很糟糕:

  • 使用s/'//g;

    删除所有单引号

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

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

    从我的几次尝试中看起来几乎是不可能的。

最佳做法是什么?

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:2)

有三种方法:

  • 找到一个为您执行SQL注入检测的CPAN库。我读了关于SQL::Abstract的好消息。

  • 使用quote_identifier

  • 使用 binding 参数(在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的值到查询中的第一个“?”是

朗德施瓦茨的文章here是一本很好的阅读材料。