0

我正在编写一个快速的 Perl 脚本,它接受用户输入并将其用作 MySQL 正则表达式。我想确保我可以在没有任何Bobby 桌子废话的情况下通过它。特别是,我希望允许使用各种特殊字符,同时拒绝任何可能超出引用本身的内容。

代码是这样的:

my $myRegex = join(' ', @ARGV);
# ...other code...
sendToSQL("select blah from foo where bar regexp '$myRegex'");

特别是,我需要像\(...\)and这样的结构\.来保留——我不能将它们更改为\\\(...\\\)and \\.。感觉这很简单,它应该已经存在了——我不想在这里重新发明轮子。

该脚本仅通过 SSH 接收来自受信任用户(包括我自己在内的三个用户之一)的输入,因此“原则上”我可以不加检查地传递字符串。但是,如果它发现了诚实的错误,而不是无意中将部分命令泄露给 SQL 并导致奇怪的结果,我会感觉好多了。(这本身不是安全问题有权访问脚本的用户已经可以直接运行 mySQL。)

编辑:建议的副本仅与我的问题略有相关,当然不是它的副本。我没有使用 DBI,我担心的不是注入攻击——担心的是用户不会无意中导致数据库副作用,而不是敌对方在其上运行恶意代码。(为了使用脚本,您需要已经可以直接访问 MySQL,在这种情况下,您可以对数据库进行任意更改。)

4

3 回答 3

2
my $sth = $dbh->prepare("select blah from foo where bar regexp ".$dbh->quote($myRegex));
$sth->execute();

或者

my $sth = $dbh->prepare("select blah from foo where bar regexp ?");
$sth->execute($myRegex);

请注意,正则表达式很昂贵,因此这仍然会对服务器产生不利影响。

于 2016-01-28T22:00:26.120 回答
1

如果不能选择使用带有绑定占位符的预准备语句,那么您当然需要“转义”SQL 文本中提供的潜在不安全值。

唯一需要转义的字符是反斜杠字符和用于包围字符串的引号字符。

您使用单引号将值括起来。正则表达式中的反斜杠字符之前需要有另一个反斜杠字符。由于您使用单引号将字符串括起来,因此值中的任何单引号需要以反斜杠字符开头。

您可以转义其他字符,例如双引号,但这在您的特定情况下并不是绝对必要的。但是逃避双引号字符不会有任何伤害。

编写该sendToSQL函数的人还应该提供一个相应的escapeForSQL函数作为 DBI“引用”函数的包装器:

sendToSQL("select blah from foo where bar regexp '" . escapeForSQL($myRegex) . "'");
于 2016-01-28T22:10:08.453 回答
0

正确的方法是遵循bobby-tables.com 上的建议并在查询中使用占位符。

于 2016-01-28T22:00:14.757 回答