Как отменить системный вызов в CGI.pm

У меня есть следующий скрипт 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 ответа

Весь смысл заражения состоит в том, чтобы гарантировать, что непроверенный ввод не может быть передан потенциально небезопасным функциям.

В этом случае ваш $searchterm переменная может содержать неожиданный ввод, который может позволить злоумышленнику выполнить произвольные программы в вашей системе.

Следовательно, вам либо нужно:

  1. Отключите переменную, убедившись, что она соответствует заранее заданному регулярному выражению (см. ответ @flesk), и в этот момент Perl предполагает, что вы знаете, что делаете, или

  2. не используйте обратные пометки (за ответ @eugene y).

Если вы используете обратные метки, вы также должны указать полный путь к grep команда, чтобы вы не зависели от $PATH,

Используйте встроенный grep функция, например:

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

Я думаю, что проблема здесь в том, что оператор back tick эффективно выполняет код вне среды perl, и поэтому совершенно справедливо не является доверенным, т.е. испорчена.

Конечно, вы можете попробовать сделать что-то вроде этого перед ошибочной строкой:

$ENV{"PATH"} = "";

Вы, вероятно, все еще получите сообщение об ошибке в этой строке:

my $file = "justafile.txt";

Чтобы это исправить, вы можете просто указать абсолютный путь, например:

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

Вам почти наверняка придется указать абсолютный путь к команде grep, которую вы выполняете с помощью оператора back tick, так как очистка переменных окружения потеряет путь. Другими словами:

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

Вы также можете скопировать значение $ENV прежде чем очистить его, на случай, если оно понадобится вам позже...

Надеюсь, что это поможет!

-T Переключатель только предупреждает вас о возможном запятнанном вводе: http://perldoc.perl.org/perlsec.html

Вы должны отключить его самостоятельно, например, используя

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

Это не очень сложный тест, и, возможно, не слишком безопасный, если у вас нет полного контроля над тем, что \w Матчи.

РЕДАКТИРОВАТЬ: изменил мое минимальное решение, чтобы отразить информацию, приведенную в комментариях ниже.

Другие вопросы по тегам