web-dev-qa-db-ja.com

HTTP URLのパス部分のエンコードされたスラッシュ( "%2F")と同等のスラッシュ( "/")です

URLのパス部分(クエリ文字列ではない)の「/」と「%2F」を異なる方法で処理するサイトがあります。これは、RFCまたは現実世界のいずれかに従って行うのは悪いことですか?

私が使用しているWebフレームワーク(Ruby on Rails)とその下のレイヤー(Passenger、Apache、たとえば、Apacheの "ALLOW_ENCODED_SLASHES"を有効にする必要がありました)で少し驚きにぶつかってしまうためです。現在、エンコードされたスラッシュを完全に取り除くことに傾いていますが、エンコードされたスラッシュに関連する奇妙な動作が見られるバグレポートを提出する必要があるのでしょうか。

最初にエンコードされたスラッシュがある理由については、基本的に次のようなルートがあります:

:controller/:foo/:bar

ここで、:fooは、スラッシュを含むことができるパスのようなものです。最も簡単なことは、URLエスケープfooだけにすることだと思ったので、スラッシュはルーティングメカニズムによって無視されます。今私は疑問を抱いており、フレームワークがこれを実際にサポートしていないことはかなり明らかですが、RFCによると、このようにするのは間違っていますか?

ここに私が集めたいくつかの情報があります:

RFC 1738(URL):

通常、URLは、オクテットが文字で表される場合とエンコードされる場合に同じ解釈を持ちます。ただし、これは予約文字には当てはまりません。特定のスキームに予約されている文字をエンコードすると、URLのセマンティクスが変更される場合があります。

RFC 2396(URI):

これらの文字は、URIコンポーネント内での使用が予約された目的に限定されているため、「予約」と呼ばれます。 URIコンポーネントのデータが予約された目的と競合する場合、URIを形成する前に競合するデータをエスケープする必要があります。

(ここでエスケープすることは、予約文字をエンコードすること以外のことを意味しますか?)

RFC 2616(HTTP/1.1):

「予約済み」および「安全でない」セット(RFC 2396 [42]を参照)以外の文字は、「%」HEX HEX」エンコーディングと同等です。

Railsには このバグレポート もあり、エンコードされたスラッシュが異なる動作をすると予想されるようです。

確かに、異なるリソースを指しているため、異なる結果が期待されます。

ルートディレクトリでリテラルファイル「foo/bar」を探しています。エスケープされていないバージョンは、ディレクトリfoo内でファイルバーを探しています。

RFCから、未処理の文字とエンコードされた文字は予約されていない文字と同等であることは明らかですが、予約された文字の話は何ですか?

57
user85509

収集したデータから、uriでエンコードされた「/」は、application/cgiレベルで再び「/」と見なされることになっていると言えます。

つまり、mod_rewriteでApacheを使用している場合、スラッシュがエンコードされたURIに対してスラッシュを期待するパターンと一致しません。ただし、リクエストを処理するために適切なmodule/cgi/...が呼び出されたら、デコードを実行し、たとえば、URIの最初のコンポーネントとしてスラッシュを含むパラメーターを取得します。

アプリケーションがこのデータを使用してファイル(ファイル名にスラッシュが含まれる)を取得する場合、それはおそらく悪いことです。

要約すると、「/」または「%2F」での動作の違いは、それらの解釈が異なるレベルで行われるため、完全に正常であることがわかります。

28
Zeograd

の物語 %2F vs /は、最初の W3C勧告 によると、スラッシュ"階層構造を暗示する必要がある"

例2

URI

http://www.w3.org/albert/bertram/marie-claude

そして

http://www.w3.org/albert/bertram%2Fmarie-claude

2番目の場合、エンコードされたスラッシュには階層的な意味がないため、同一ではありません。

15
Yury Kirienko

また、URLエンコードされた文字を含む多数のURLがあるサイトもあります。多くのWeb API(Google WebmasterツールといくつかのDrupal=モジュール)がurlencoded文字を介してトリップすることがわかりました。多くのAPIは、プロセスのある時点でURLを自動的にデコードし、結果をURLとして使用しますこれらの問題の1つを見つけた場合、通常はそのAPIの結果をダブルエンコード(%2fから%252fに変換)しますが、ダブルエンコードを想定していない他のAPIが破損するため、これは普遍的ではありません溶液。

個人的には、URL内のできるだけ多くの特殊文字を取り除きます。

また、urldecodingに依存しないURLでID番号を使用しています。

example.com/blog/my-amazing-blog%2fstory/yesterday

になる:

example.com/blog/12354/my-amazing-blog%2fstory/yesterday

この場合、コードは12354のみを使用して記事を検索し、URLの残りはシステムによって無視されます(ただし、SEOには引き続き使用されます)。また、この番号は未使用のURLコンポーネントの前に表示されます。そうすれば、%2fが誤ってデコードされた場合でも、URLは引き続き機能します。

また、URLの間違いが重複したコンテンツに変換されないように、必ず標準タグを使用してください。

9
Hoytman

Tomcatを使用する場合は、VMプロパティに '-Dorg.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = true'を追加します。

https://Tomcat.Apache.org/Tomcat-7.0-doc/config/systemprops.html#Security

3
zhe liu

:fooその自然な形にはスラッシュが含まれていますか?あなたはそれを望んでいないだろうthat勧告が保持しようとしている区別ではない? 特に注意

UNIXおよび他のディスクオペレーティングシステムのファイル名の規則との類似性は、単なる偶然と見なされるべきであり、URIがファイル名として解釈されるべきであることを示すと解釈されるべきではありません。

バックアッププログラムへのオンラインインターフェイスを構築していて、パスをURLパスの一部として表現したい場合は、ファイルパスのスラッシュをエンコードするのが理にかなっていますnotは実際にはリソースの階層の一部です。さらに重要なことは、routeです。 /backups/2016-07-28content//home/dan/は、二重スラッシュでファイルシステムのルートを失います。私が読んだように、スラッシュをエスケープすることは区別する適切な方法です。

2
Daniel Farrell