如何在CGI.pm中解开系统调用

时间:2011-11-22 13:41:38

标签: perl cgi taint

我有以下CGI脚本:

#!/usr/bin/perl -T
use strict;
use warnings;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard/;
my $query = CGI->new();
my $searchterm = param('name');

my $file = "justafile.txt";
# Begin searching terms and ignoring case
my @entries = `grep -i \"$searchterm\" $file`; # Line10
chomp @entries;
# Do something

当我执行命令时,它会给我这个

Insecure dependency in `` while running with -T switch at /foo/cgi-bin/mycode.cgi line 10.

如何修复第10行?

4 个答案:

答案 0 :(得分:8)

污点的全部意义在于确保无法将未经检查的输入提供给潜在的不安全功能。

在这种情况下,您的$searchterm变量可能包含可能允许攻击者在您的系统上执行任意程序的意外输入。

因此,您需要:

  1. 取消变量,确保它与预先确定的正则表达式匹配(请参阅@ flesk的答案),此时Perl假定您知道自己在做什么,或者

  2. 不要使用反引号(根据@eugene y的回答)。

  3. 如果您正在使用反引号,则还应指定grep命令的完整路径,这样您就不会依赖$PATH

答案 1 :(得分:5)

使用内置grep功能,例如:

open my $fh, '<', $file or die $!;    
my @entries = grep /$searchterm/i, <$fh>;

答案 2 :(得分:3)

-T开关只会警告您可能受到污染的输入:http://perldoc.perl.org/perlsec.html#Taint-mode

您需要自己解开它,例如使用

my $safe_searchterm = "";
$safe_searchterm .= $_ for $searchterm =~ /\w+/g;

这不是一个非常复杂的测试,也可能不太安全,除非你完全控制\w匹配的内容。

编辑:更改了我的最小解决方案,以反映以下评论中提供的信息。

答案 3 :(得分:3)

我认为这里的问题是反引号操作符有效地执行perl环境之外的代码,因此非常不正确,即。污点。

当然,您可以在违规行之前尝试做类似的事情:

$ENV{"PATH"} = "";

您可能仍会从此行收到错误:

my $file = "justafile.txt";

要解决这个问题,你可以给它一个绝对路径,例如:

my $file = "/home/blah/justafile.txt";

您几乎肯定必须给出使用反引号运算符执行的grep命令的绝对路径,因为清除环境变量会使路径松散。换句话说:

# Begin searching terms and ignoring case
my @entries = `/bin/grep -i \"$searchterm\" $file`; # Line10

您可能还想在清除它之前复制$ENV的值,以防以后需要它...

希望其中一些有帮助!