【问题标题】:Issue with filepath name, possible corrupt characters文件路径名称问题,可能是损坏的字符
【发布时间】:2013-04-03 21:05:30
【问题描述】:

Perl 和 html,Linux 上的 CGI。 文件路径名问题,在表单字段中传递给服务器上的 CGI。 问题在于 Linux 文件路径,而不是 PC 端。

我正在使用 2 个程序, 1) 多年前写的程序,在perl程序中生成动态html,并以表格形式呈现给用户。我通过插入所需的代码进行修改,以允许用户从他们的 PC 中选择一个文件,并将其放置在 Linux 机器上。

因为这个程序已经知道 linux 端需要的文件路径,所以我将这个文件路径放在一个隐藏的表单字段中,传递给程序 2。

2) Linux 端的 CGI 程序,在 (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的调用没有失败,它按预期执行了下面if的else块。

这里是文件打开块:

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 出现相同的错误,尽管字符看起来完全相同。

【问题讨论】:

  • 冒着听起来很愚蠢的风险,但您查看过网络服务器错误日志吗?
  • 我也冒着听起来很愚蠢的风险,您确定您将这些值与“eq”运算符而不是“==”($fpath1 eq $fpath2) 进行比较?
  • 从 CGI 请求中读取服务器文件位置的路径是一个潜在的严重漏洞。不要这样做。
  • Re "但是不管我做什么,使用 $fpath1 都会出错" 什么错误??? (在错误信息中添加$!
  • 如果路径有问题,use Dumper; local $Data::Dumper::Useqq = 1; warn(Dumper($fpath1, $fpath2)); 会显示出来。

标签: linux perl file cgi


【解决方案1】:

您的 CGI 是否可能使用-T(污点模式)开关(例如,#!/usr/bin/perl -T)运行 perl?如果是这样,任何来自不受信任的来源(例如用户输入、URI 和表单字段)的值都不允许在系统操作中使用,例如 open,直到通过使用正则表达式捕获来清除它。请注意,使用s/// 就地修改它不会取消该值。

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

如果污点模式是您的问题,应该可以工作。

【讨论】:

  • 感谢您的回答和见解。原来是使用了受污染的旗帜。我正在使用-wT。不使用 T 标志有效。
  • @user2234591 在这种情况下使用-T 标志实际上是一个好主意。它可以防止你做一些愚蠢的事情;就像读取服务器上的随机文件一样。
  • unless( ($fpath1) = $fpath1 =~ /^([A-Z])$/ ){ die ... } 也可以。
【解决方案2】:

但它失败了,而且不是以一种将我带到文件打开错误块的方式,而是对 CGI 脚本的调用给出了一个错误。

脚本标题过早结束?尝试从命令行运行 CGI:

perl your_upload_script.cgi serverfpath=/opt/webhost/ims/DOCURVC/data

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多