假设给出了以下Perl代码:
my $user_supplied_string = &retrieved_from_untrusted_user();
$user_supplied_string =~ s/.../.../g; # filtering done here
my $output = `/path/to/some/command '${user_supplied_string}'`;
代码显然不安全,但假设可以更改的唯一是第2行的过滤代码。
我的问题:
请注意:
答案 0 :(得分:5)
首先,鉴于您关注安全性,我建议您研究taint mode。至于允许shell可见的最小字符集,最好不要让shell看到任何字符:
my $output = do {
local $/;
open my $pipe, "-|", "/path/to/some/command", $user_supplied_string
or die "could not run /path/to/some/command: $!";
<$pipe>;
};
答案 1 :(得分:0)
经过一些研究后,以下可能是您正在寻找的最小集合,至少在类UNIX系统的子集上。当然,我没有亲自测试过,所以YMMV:
&;`'\"|*?~<>^()[]{}$\n\r
在正则表达式中:
s/[\&\;\`\'\\\"\|\*\?\~\<\>\^\(\)\[\]\{\}\$\n\r]//g
我认为在实际代码中实际使用它不是一个好主意,但我可以看出它是如何因为纯粹的好奇而感兴趣。
答案 2 :(得分:0)
您允许的字符集取决于系统调用中的应用程序将对其执行的操作。有shell特殊字符,但这只是问题的一部分。您还必须确保为命令提供的值是有效输入,这需要更多的工作。
例如,请参阅Mastering Perl中关于安全性的章节,其中我将详细介绍问题。
也许你可以解释为什么你的问题会将你的双手绑在背后并使你蒙上眼睛。如果这些是您的约束,那么您的问题不是技术问题。