perl函数dbh-> quote是否仍然安全?

J.D*_*Doe 1 sql perl escaping

我目前正在perl中编写一个小脚本来连接到我的数据库,检索一些数据并将其显示给用户.检索的数据取决于用户给出的参数.

dbh->quote用来逃避报价:

...
my $dbh=DBI->connect(***);

my $myquery="SELECT * FROM customers WHERE clientName =".$dbh->quote(param('name')) . " AND pass =".$dbh->quote(param('pass'));
my $sth=$dbh->prepare($myquery);
$sth->execute();

my $output=$sth->fetch();
if ($output){
    print @$output;
}
...
Run Code Online (Sandbox Code Playgroud)

一位朋友告诉我,这可能不安全,并且他读到有人发现了漏洞.我刚刚开始使用perl,但我想了解这个漏洞是什么.

经过一番挖掘后,我发现这个文件(pdf)似乎在谈论它,但我无法重现这个bug.

hob*_*bbs 10

问题主要不在于quote本身.quote如果使用得当,则是安全的(尽管在这种情况下它不是最佳选择).但是,如果paramparam从CGI.pm,或其他任何东西,也有类似的行为,你有一个很大的问题.

你看,param是上下文敏感的.在标量上下文中,如果参数具有单个值(name=foo),则返回该值,如果参数具有多个值(name=foo&name=bar),则返回arrayref.在列表上下文中,它返回值列表,无论是零,一还是多.方法(例如quote)的参数列表是列表上下文.这意味着使用您的应用程序的人可能会导致quote接收两个值,而quote可选的第二个参数是一个SQL数据类型,第一个参数应该被视为.如果数据类型是非字符串类型NUMERIC,quote则将通过其第一个参数而不进行任何引用.这构成了SQL注入的机会.

建议:

  1. 虽然quote使用得当是安全的,但占位符更好,更安全,更难以使用.尽可能使用DBI占位符,而不是quote.

  2. 不要param在参数列表,哈希构造函数或任何其他可能返回意外数量的项目并破坏您的一天的地方使用CGI .要么放在scalar前面,要么指定标量,要么分配给数组.或者,更好的是,完全避免使用CGI.pm和workalike接口.

  3. 不要将密码以纯文本形式存储在数据库中.一旦有人确实可以访问数据库的部分,用户的密码将被暴露给他们.密码应该被散列,并且有很好的,易于使用的Perl模块(Authen :: Passphrase).

  4. 不要将密码作为URL参数传递.URL很容易通过HTTP引用,浏览器历史记录,粗心的复制/粘贴等泄露.密码应以表单形式发布,最好通过安全连接.