在将值传递给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注入
从我的几次尝试中看起来几乎是不可能的。
最佳做法是什么?
答案 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
的好消息。
使用 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是一本很好的阅读材料。