regex - Perl 正则表达式作为用户搜索输入(清理)
问题描述
我需要确保作为用户输入传递的regex不会意外终止并变成任意Perl 代码,但同时用于基本过滤目的。
重要的!这部分代码在用户监狱模式下运行,这意味着它可能只能被自我利用。除此之外,UI 只暴露给特定用户,并且可能针对有限数量的文件运行,因此潜在的 DoS 风险非常小。
为了达到我的目标,我创建了一个自定义函数,它首先将引用元全部,然后取消转义,只需要正则表达式来运行字符。
例子:
# Allow short range of special chars to be left unescaped
# to let regex work, while at the same time prevent possible
# command injection or premature regex termination
my $mask = $in{'mask'};
sub quotemeta_dangerous
{
my ($string) = @_;
$string = quotemeta($string);
$string =~ s/\\\\/\\/g;
$string =~ s/\\\+/+/g;
$string =~ s/\\\*/*/g;
$string =~ s/\\\$/\$/g;
$string =~ s/\\\^/\^/g;
$string =~ s/\\\(/\(/g;
$string =~ s/\\\)/\)/g;
$string =~ s/\\\{/\{/g;
$string =~ s/\\\}/\}/g;
$string =~ s/\\\[/\[/g;
$string =~ s/\\\]/\]/g;
$string =~ s/\\\?/?/g;
$string =~ s/\\\././g;
$string =~ s/\\\-/-/g;
return $string;
}
my $sanitized_mask = quotemeta_dangerous($mask);
if ($filename =~ /$sanitized_mask/) {
# matched
}
问题:
考虑到提到的重要旁注,我上面的解决方案是否会帮助我安全地实现我的目标。我在这里看不到的潜在风险是什么?
作为一个熟悉的问题,当进一步运行替换时,替换部分是否也可以被注入/利用,如果是,如何安全地在匹配文件的内容中运行替换?
例子:
$file_contents =~ s/\Q$text_to_find\E/$text_to_replace_with/g;
$text_to_replace_with
当从用户原样传递时,是否可以在此处避免安全风险?
解决方案
我不确定您所说的终止是什么意思。至于运行任意 Perl 代码,您不能通过用户输入来执行此操作(除非程序使用 eg
eval()
或显式启用它use re 'eval'
)。如果您可以只从用户输入中注入 Perl 代码,您的函数将无法防范它:它允许通过例如(?{system+qq(rm -rf ~)})
可运行形式(可运行,也就是说,如果它是代码的一部分,而不是输入数据)。您可以使用用户输入正则表达式执行的操作是创建 DoS:使其消耗大量 CPU 并挂起程序。您的功能不能防止这种情况。例如,尝试:
'aaaaaaaaaa' =~ /(((\1?[a-z]*)*)*)*[b-z]/
或者带有更长的a链。(可能有一些方法可以缩短此代码;我只是将随机位放在一起,看看它们是否快速完成匹配。)
如果您想防止这种情况,请查看RE2:
RE2 的设计和实施具有明确的目标,即能够无风险地处理来自不受信任用户的正则表达式。
您可以通过执行在代码中使用它
{ use re::engine::RE2 -strict => 1; # now regexes compiled in this scope will use the RE2 engine ... }
这很容易回答。这里没有危险;
$text_to_replace_with
被简单地视为一个字符串。(如果你想制造危险,你需要
/e
和eval()
, 或/ee
,这是同一回事。
从技术上讲,您不需要,但这仍然会在您的代码中
/e
留下非常明显的内容。eval()
同样,您不能以用户身份攻击它;你必须把它编码进去。)
推荐阅读
- scikit-learn - sklearn 在项目内部或外部是否有任何模型类型元数据?
- wsdl - BPEL 和 ESB:SOA 概述
- android - 从适用于模拟器和物理设备的 ImageView 上的 URL 显示位图的正确方法?
- android - App Bundle 是否足够或减少 APK 大小所需的 APK 拆分?
- windows - 如何以当前文件夹的名称保存文件的组合内容?
- php - 如何使用 PHP 中的嵌套函数从所选类别中选择子类别?
- csv - 将 CSV 文件导入 neo4j 的急切操作员警告
- docker - 需要澄清 openshift docker 映像中的文件存储
- oracle - Oracle 日期和时间提示
- java - SQL 错误:1064,SQLState:42000,如果在 sqlworkbench 中单独执行,则工作正常