Как отменить системный вызов в 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
переменная может содержать неожиданный ввод, который может позволить злоумышленнику выполнить произвольные программы в вашей системе.
Следовательно, вам либо нужно:
Отключите переменную, убедившись, что она соответствует заранее заданному регулярному выражению (см. ответ @flesk), и в этот момент Perl предполагает, что вы знаете, что делаете, или
не используйте обратные пометки (за ответ @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
Матчи.
РЕДАКТИРОВАТЬ: изменил мое минимальное решение, чтобы отразить информацию, приведенную в комментариях ниже.