0

我有一个处理 URL 的 perl 脚本 - 在服务器升级之前它工作正常。现在它似乎对它返回的 URL 字符串进行了双重编码。

以下是脚本用于返回的 URL 示例:

https://processor.com/?&streetOne=johndoe%40test%2Ecom&key=1234

这就是它现在返回的内容

https://processor.com/?&email=johndoe%2540test%252Ecom&key=1234

它们的关键区别在于,@URL 中的 曾经被正确编码,%40但现在百分号正在被编码(双重编码),所以%2540如果你@对它进行编码然后再次对其进行编码,就会发生这种情况。

我不确定服务器上会发生什么变化导致这种行为。我是一个 PHP 人,它让我想起了“魔术引号”,它会在脚本处理之前自动转义要接收的所有查询变量。

我没有对该服务器的 root 访问权限,因此如果无法使用.htaccess文件或某些本地配置选项(在 perl 脚本中?)进行更改,那么我可能需要更改此函数中发生的情况,即获取请求的每个 URL 值:

首先脚本读取查询变量

(我认为这可能是问题所在 - 我不理解正则表达式 - 关于在空格之间寻找 KEY 以及该$obj->{'key'};部分正在做什么)

sub getValue
{
  my $obj = shift;
  my $name = shift;

  if ($name =~ /^\s*KEY\s*$/i)
    {
      return $obj->{'key'};
    }

  if (! $obj->isValid($name))
    {
      $obj->addError("Cannot obtain information for field '$name' since field is invalid");
      return 0;
    }

  if (! $obj->isAssigned($name))
    {
      $obj->addError("Cannot obtain value from field '$name' since field has not be assigned a value.");
      return 0;
    }

  return $obj->{'parameters'}->{ $name }->{ 'value'};
}

然后脚本将查询变量构建回 URL 以返回:

脚本的另一部分构建了它返回的 URL - 但我认为这不是罪魁祸首。我尝试CGI::escapeCGI::escape($value))零件中删除它并没有帮助。

sub create_results
{
  my $obj = shift;

  my ($seconds, $microseconds) = gettimeofday();
  my $timestamp = int($seconds*1000 + $microseconds/1000);

  $obj->assign('timestamp',$timestamp);

  # create query string and hash data

  my $hash_data = '';

  my @query_string = qw();

  foreach my $name (@{ $obj->{'parameter_order'} })
    {
      my $node = $obj->{'parameters'}->{ $name };

      if (defined($node->{'value'}))
        {
          my $value = $node->{'value'};
          $hash_data .= $value;

          # $query->param(-name=>"$name",   -value=>"$value");
          push(@query_string,$name . "=" . CGI::escape($value));
        }
    }

  # Hash
  $hash_data .= $obj->get('key');
  my $hash_digest = md5_hex( $hash_data );

  push(@query_string, "hash=$hash_digest");

  $obj->{'query_string'} = join("&",@query_string);
  $obj->{'hash_digest'} = $hash_digest; 
}

该脚本是我正在使用的 perl 包。我没写。我在这里发布了完整的脚本:http: //pastebin.com/eZr8rQ0t

4

1 回答 1

1

使用 CGI 模块有点过时,并且CGI::escape是一个未记录的内部函数,它CGI::Util适用于 CGI 内部。有一个相应的功能可用,但这几乎不是正确的事情。unescape

为了缩短追逐时间,使用CGI::Util::unescape($dirty_value)某处应该可以工作,因为该模块应该由CGI. 也许在returnfrom getValue,但我很累找不到正确的地方。这种双重编码似乎是一个设计错误,或者假设您提供的示例 URL 已经被转义,并且脚本使用错误。

我敢打赌错误的设计;考虑到有人认为这样做很有趣

"foo" => { "parameterName" => "foo" },
... # snip like 50 other values
"quux" => { "parameterName" => "quux" },

以及其他一些map { $_ => {parameterName => $_} } qw/foo ... qux/只需要打字就可以工作的愚蠢……</p>

提示:所有(公共)Perl 模块(包括源代码)的文档可在https://metacpan.org/获得。

于 2013-02-05T05:25:07.747 回答