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の男で、スクリプトが処理する前に、すべてのクエリ変数を自動エスケープして受け取る「魔法の引用符」を思い出します。

私はこのサーバーへのルート アクセス権を持っていないため、.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::escape部品からを取り外してみましたが、CGI::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)どこかを使用すると、そのモジュールが によってロードされているはずなので、動作するはずですCGIreturnからかもしれませ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 に答える