简体   繁体   English

转义字符串在Perl中引用

[英]Escaping string to be quoted in Perl

I'm writing a quick Perl script which takes user input and uses it as a MySQL regex. 我正在编写一个快速的Perl脚本,该脚本需要用户输入并将其用作MySQL正则表达式。 I'd like to ensure that I can pass it without any of the Bobby tables nonsense. 我想确保我可以通过它,而不会出现任何Bobby表废话。 In particular, I want to allow all kinds of special characters, while rejecting anything that could break out of the quote itself. 特别是,我要允许各种特殊字符,同时拒绝任何可能超出引号本身的内容。

The code is something like this: 代码是这样的:

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

In particular, I need constructs like \\(...\\) and \\. 特别是,我需要像\\(...\\)\\.这样的构造\\. to remain -- I can't change them to \\\\\\(...\\\\\\) and \\\\. 保留-我无法将它们更改为\\\\\\(...\\\\\\)\\\\. . It feels like this is simple enough it should exist already -- I'm trying to not reinvent wheels here. 感觉这已经足够简单了,应该已经存在了-我试图在这里不重新发明轮子。

The script receives input only from trusted users (one of three, including myself) over SSH, so 'in principle' I could just pass the string along unchecked. 该脚本仅通过SSH接收来自受信任用户(包括我在内的三个用户之一)的输入,因此“原则上”,我可以不加检查就传递字符串。 But I'd feel much better if it caught honest mistakes rather than inadvertently leaking partial commands to SQL with weird results. 但是,如果它捕获了诚实的错误,而不是不经意间将部分命令泄漏给SQL并产生奇怪的结果,我会感觉好多了。 (This is not a security issue per se: the users who have access to the script can already run mySQL directly.) (这本身不是安全问题有权访问脚本的用户已经可以直接运行mySQL。)

Edit: The proposed duplicate is only slightly related to my issue and certainly not a duplicate of it. 编辑:建议的副本仅与我的问题稍有相关,当然也不能重复。 I'm not using DBI and my concern is not injection attacks -- the concern is that a user not inadvertently cause database side effects, not that a hostile party runs malicious code on it. 我没有使用DBI,我的关注点不是注入式攻击-关心的是用户不会无意中引起数据库副作用,而不是敌意的一方在其上运行恶意代码。 (In order to use the script you need to already have access to MySQL directly, in which case you could make arbitrary changes to the db already.) (为了使用脚本,您需要已经可以直接访问MySQL,在这种情况下,您可以对数据库进行任意更改。)

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

or 要么

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

Note that regular expressions are expensive, so this can still have an adverse effect on the server. 请注意,正则表达式很昂贵,因此这仍然会对服务器产生不利影响。

If using a prepared statement with bind placeholder isn't an option, then you certainly do need to "escape" potentially unsafe values supplied in the SQL text. 如果不能使用带有绑定占位符的预处理语句,那么您当然需要“转义” SQL文本中提供的潜在不安全值。

The only characters that need to be escaped are the backslash character, and the quote character used to enclose the string. 唯一需要转义的字符是反斜杠字符和用于将字符串括起来的引号字符。

You're using a single quote to enclose the value. 您使用单引号将值括起来。 The backslash characters within the regular expression are going to need to be preceded by another backslash character. 正则表达式中的反斜杠字符必须在另一个反斜杠字符之前。 And since you are using single quotes to enclose the string, any single quotes within the value will need to be preceded by a backslash character. 并且由于您使用单引号将字符串括起来因此值中的任何单引号都必须在其后加上反斜杠字符。

You could escape additional characters, like a double quote, but that's not strictly necessary in your particular case. 您可以转义其他字符,例如双引号,但是在您的特定情况下,这并非绝对必要。 But it wouldn't hurt anything to escape the double quote character. 但是逃脱双引号字符不会有任何伤害。

Whoever wrote the sendToSQL function should have also provided a corresponding escapeForSQL function as a wrapper to the DBI "quote" function: 编写sendToSQL函数的人也应该提供相应的escapeForSQL函数作为DBI“ quote”函数的包装器:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM