在将字符串传递给系统调用之前,我需要过滤的最小字符集是什么?

时间:2009-09-05 17:33:35

标签: perl security

假设给出了以下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行的过滤代码。

我的问题:

  • 为了使上述代码安全,需要在第2行过滤的最小字符集是什么?

请注意:

  • 在这种情况下,白名单不是一种选择,因此请将您的答案集中在过滤掉哪些内容以确保其安全。更具体地说;为了使其安全而过滤掉的最小字符集是什么?其他一切都是偏离主题的。
  • 确保您的答案解决了所述问题(“最小字符集是什么需要在第2行上过滤以使上述代码安全?”)。如果您的答案没有解决这个非常具体的问题,那么请不要发帖。感谢。

3 个答案:

答案 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中关于安全性的章节,其中我将详细介绍问题。

也许你可以解释为什么你的问题会将你的双手绑在背后并使你蒙上眼睛。如果这些是您的约束,那么您的问题不是技术问题。