转义要在 Perl 中引用的字符串

Escaping string to be quoted in Perl

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

代码是这样的:

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

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

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

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

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

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);

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

如果使用带有绑定占位符的准备好的语句不是一个选项,那么您当然需要 "escape" SQL 文本中提供的潜在不安全值。

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

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

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

编写 sendToSQL 函数的人应该也提供了相应的 escapeForSQL 函数作为 DBI "quote" 函数的包装器:

sendToSQL("select blah from foo where bar regexp '" . escapeForSQL($myRegex) . "'");