Проблема с именем пути к файлу, возможные поврежденные символы

Perl и HTML, CGI в Linux. Проблема с именем пути файла, передаваемого в поле формы, в CGI на сервере. Проблема связана с путем к файлу Linux, а не с ПК.

Я использую 2 программы, 1) программу, написанную несколько лет назад, динамический HTML, созданный в Perl-программе и представленный пользователю в виде формы. Я изменил, вставив необходимый код, чтобы пользователь мог выбрать файл на своем ПК для размещения на компьютере с Linux.

Поскольку эта программа уже знала путь к файлу, необходимый на стороне Linux, я передаю этот путь к файлу в скрытом поле формы программе 2.

2) CGI-программа на стороне Linux, запускаемая при размещении формы в (1).

Странный вопрос. Путь к файлу, который я передаю, имеет очень странную проблему. Я могу извлечь это, используя

my $filepath = $query->param("serverfpath");

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

Однако, если я наполнил $filepath ТОЧКО той же строкой, через жесткое кодирование, это сработает, и мой файл успешно загрузится.

Например:

$fpath1 = $query->param("serverfpath");
$fpath2 = "/opt/webhost/ims/DOCURVC/data" 

Сравнение $fpath1 и $fpath2 показывает, что они в точности равны. Проверка длины $fpath1 и $fpath2 показывает, что они абсолютно одинаковой длины.

Я перепробовал много способов очистки данных в $fpath1. Я жму это. Я удаляю любые нестандартные символы.

$fpath1  =~ s/[^A-Za-z0-9\-\.\/]//g;

и это:

my $safe_filepath_characters = "a-zA-Z0-9_.-/";
$fpath1 =~ s/[^$safe_filepath_characters]//g;

Но что бы я ни делал, использование $fpath1 приводит к ошибке, использование $fpath2 работает.

Что может быть не так с данными в $fpath1, что может привести к тому, что они будут успешно сравниваться с $fpath2, но не будут равны, визуально выглядят абсолютно равными, будут иметь одинаковую длину, но не работать одинаково?

Для приведенного ниже файла откройте блок.

$upload_dir = $fpath1 

вызывает полную неудачу загрузки CGI, как будто он не может найти CGI (что, как я знаю, иногда вызывается синтаксической ошибкой в ​​скрипте CGI).

$uplaod_dir = $fpath2   

Я получил успешную загрузку файла

$uplaod_dir = ""        

Вызов cgi не завершается ошибкой, он выполняет блок else из приведенного ниже if, как и ожидалось.

вот блок открытия файла:

if (open ( UPLOADFILE, ">$upload_dir/$filename" ))   
{
binmode UPLOADFILE;

while ( <$upload_filehandle> )
{
print UPLOADFILE;
}

close UPLOADFILE;
$msgstr="Done with Upload: upload_dir=$upload_dir filename=$filename";
}
else
{
$msgstr="ERROR opening for upload: upload_dir=$upload_dir filename=$filename";
}

Какие еще тесты я должен выполнить для $fpath1, чтобы выяснить, почему он не работает так же, как его жестко запрограммированный эквивалент $fpath2

Я пробовал замену символов, по одному символу за раз, от $fpath2 до $fpath1. Даже выполнение этого с одним символом приводило к тому, что $fpath1 имел ту же ошибку, что и $fpath2, хотя символ выглядел точно так же.

2 ответа

Решение

Ваш CGI, возможно, работает на Perl с -T (режим порчи) (например, #!/usr/bin/perl -T)? Если это так, любое значение, поступающее из ненадежных источников (таких как пользовательский ввод, URI и поля формы), не может использоваться в системных операциях, таких как open до тех пор, пока он не будет обработан с помощью захвата регулярных выражений. Обратите внимание, что с помощью s/// изменить его на месте не приведет к отмене значения.

$fpath1  =~ /^([A-Za-z0-9\-\.\/]*)$/;
$fpath1 = $1;
die "Illegal character in fpath1" unless defined $fpath1;

Должен работать, если ваша проблема в режиме taint.

Но он терпит неудачу, и не таким образом, что приводит меня к блоку ошибок открытия файла, а так, что вызов сценария CGI дает ошибку.

Преждевременный конец заголовков скриптов? Попробуйте запустить CGI из командной строки:

perl your_upload_script.cgi serverfpath=/opt/webhost/ims/DOCURVC/data
Другие вопросы по тегам