Linux 文件路径名出现问题,可能是损坏的字符

Linux 文件路径名出现问题,可能是损坏的字符,linux,perl,file,cgi,Linux,Perl,File,Cgi,Linux上的Perl和html、CGI。 在表单字段中传递给服务器上CGI的文件路径名出现问题。 问题在于Linux文件路径,而不是PC端 我正在使用2个程序, 1) 多年前编写的程序,在perl程序中生成动态html,并以表单形式呈现给用户。我通过插入所需的代码进行了修改,允许用户从PC中选择一个文件,并将其放置在Linux机器上 因为这个程序已经知道linux端需要的文件路径,所以我将这个文件路径以隐藏的形式字段传递给程序2 2) Linux端的CGI程序,在发布(1)上的表单时运行 奇怪

Linux上的Perl和html、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 = ""        
对cgi的调用不会失败,它会按照预期执行下面的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";
}
if(打开(上传文件“>$upload\u dir/$filename”))
{
二进制上传文件;
而()
{
打印上传文件;
}
关闭上传文件;
$msgstr=“上传完成:上传\u目录=$Upload\u目录文件名=$filename”;
}
其他的
{
$msgstr=“打开上载时出错:upload\u dir=$upload\u dir filename=$filename”;
}
我还应该在$fpath1上执行哪些其他测试,以了解为什么它的工作方式与硬编码的等效$fpath2不同

我尝试过字符替换,一次只替换一个字符,从$fpath2到$fpath1。 即使使用单个字符执行此操作,也会导致$fpath1与$fpath2出现相同的错误,尽管该字符看起来完全相同

但是它失败了,并且不是以一种将我带到文件打开错误块的方式,而是以这样的方式调用CGI脚本会产生错误

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

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

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

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

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

冒着听起来愚蠢的风险,但是你看过Web服务器的错误日志了吗?我也冒着听起来愚蠢的风险。你确定你是在用“eq”运算符比较值,而不是“=”($fpath1 eq$fpath2)?从CGI请求读取服务器文件位置的路径是一个潜在的严重漏洞。不要这样做。Re“但无论我做什么,使用$fpath1都会导致错误”什么错误???(将
$!
添加到错误消息中)如果路径有问题,请使用转储程序;本地$Data::Dumper::Useqq=1;警告(转储程序($fpath1,$fpath2))将显示它。感谢您的回答和见解。原来是使用了受污染的国旗。我使用的是-wT。不使用T标志是有效的。@user2234591在这种情况下使用
-T
标志实际上是个好主意。它阻止你做愚蠢的事;就像读取服务器上的随机文件一样。
除非($fpath1)=$fpath1=~/^([a-Z])$/{die…}
也可以工作。
$fpath1  =~ /^([A-Za-z0-9\-\.\/]*)$/;
$fpath1 = $1;
die "Illegal character in fpath1" unless defined $fpath1;