6

[これは厳密にはプログラミングに関する質問ではないかもしれませんが、プログラマーが最もよく答えるパズルです。最初に Pro Webmasters サイトで試してみましたが、圧倒的な沈黙がありました]

当社のウェブサイトでは、メールアドレスの確認プロセスを実施しています。サイトは最初に適切なキーを文字列として生成します

mykey

次に、そのキーを一連のバイトとしてエンコードします

&$dac~ʌ����!

次に、その一連のバイトをbase64でエンコードします

JiRkYWN+yoyIhIQ==

このキーは、HTML メールに配置される URL のクエリ文字列値として提供されるため、最初にそれを URLEncode し、次に結果を HTMLEncode する必要があります (この例では HTMLEncoding の効果はありませんが、わざわざ例を作り直すことはできません)

JiRkYWN%2ByoyIhIQ%3D%3D

これは、次のような電子メールの一部として送信される HTML に埋め込まれます。

click <a href="http://myapp/verify?key=JiRkYWN%2ByoyIhIQ%3D%3D">here</a>. 
Or paste <b>http://myapp/verify?key=JiRkYWN%2ByoyIhIQ%3D%3D</b> into your browser.

受信ユーザーがリンクをクリックすると、サイトはリクエストを受信し、クエリ文字列の「キー」パラメーターの値を抽出し、base64 でデコードして復号化し、サイト ロジックの観点から適切な処理を行います。

しかし、時折、クリックが効果的ではないと報告するユーザーがいます。そのようなユーザーの 1 人が、送信された電子メールを私たちに転送しました。調べてみると、HTML は次のように変換されていました (上記の例で言えば)。

click <a href="http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D">here</a>
Or paste <b>http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D</b> into your browser.

つまり、%2B 文字列 (ただし、他のパーセンテージでエンコードされた文字列はどれも) はプラスに変換されていませんでした。(確実に正しい値が得られます - 適切な SMTP ログを調べました)。

key=JiRkYWN%2ByoyIhIQ%3D%3D
key=JiRkYWN+yoyIhIQ%3D%3D

したがって、次の 2 つの可能性があると思います。

  1. 私がやっていることは、ばかげている、見えない、または

  2. 一部のメール クライアントは %2b 文字列をプラス記号に変換します。これはおそらく、人々が誤って URL エンコーディングを行うという問題に対処するためです。

1の場合 - それは何ですか? 2 の場合 - この種のシナリオに対処するための標準的な既知の方法はありますか?

助けてくれてありがとう

4

2 に答える 2

1

問題はこの段階にあります

HTMLが変換された検査で(上記の例の観点から言えば)

click <a href="http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D">here</a>
Or paste <b>http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D</b> into
your browser.

つまり、%2B 文字列 (ただし、他のパーセンテージでエンコードされた文字列はどれも) はプラスに変換されていませんでした。

「反対側」のアプリケーションには、エスケープ解除のステップが欠落している必要があります。%2B または + があるかどうかに関係なく、perls uri_unescape のような関数は一貫した回答を返します

DB<9> use URI::Escape;
DB<10> x uri_unescape("JiRkYWN+yoyIhIQ%3D%3D")
0  'JiRkYWN+yoyIhIQ=='
DB<11> x uri_unescape("JiRkYWN%2ByoyIhIQ%3D%3D")
0  'JiRkYWN+yoyIhIQ=='

これが何が起こっているべきかです。私が示しているのは手順だけです。デバッガーで perl を使用しています。ステップ 54 は、文字列を base64 にエンコードします。ステップ 55 は、base64 でエンコードされた文字列を uri エスケープ パラメータにする方法を示しています。ステップ 56 と 57 は、クライアント エンドがデコードするために行うべきことです。

考えられる回避策の 1 つは、base64 の「キー」にプラス記号が含まれていないことを確認することです。

  DB<53> $key="AB~"
  DB<54> x encode_base64($key)
0  'QUJ+
'
  DB<55> x uri_escape('QUJ+') 
0  'QUJ%2B'
  DB<56> x uri_unescape('QUJ%2B')
0  'QUJ+'
  DB<57> $result=decode_base64('QUJ+')
  DB<58> x $result
0  'AB~'
于 2013-09-06T09:52:42.813 に答える
1

ここで発生している可能性があるのは、URLDecode が を に%2b変換+し、URL 内のスペース文字として解釈されていることです。+最初に文字列を URL デコードし、次に置換関数を使用してデコードされた文字列のスペースを文字に置き換え、次に「固定」文字列を復号化することで、同様の問題を克服することができました。

于 2016-12-28T23:33:30.557 に答える