web-dev-qa-db-ja.com

複数のスラッシュを含むURL、それは何かを壊しますか?

http://example.com/something/somewhere//somehow/script.js

ダブルスラッシュはサーバー側で何かを壊しますか? URLを解析するスクリプトがあり、複数のスラッシュを1つのスラッシュに置き換えた場合、何かが壊れる(またはパスが変更される)かどうか疑問に思っていました。特にサーバー側では、CodeIgniterやJoomlaなどの一部のフレームワークは、セグメント化されたURLスキームとルーティングを使用します。それが何かを壊すかどうか知りたいだけです。

36
Joseph

HTTP RFC 2396 はパス区切り文字を単一スラッシュと定義します。

ただし、何らかのURL書き換えを使用している場合を除き(その場合、書き換えルールはスラッシュの数によって影響を受ける可能性があります)、uriはディスク上のパスにマップされますが、(ほとんど?)最新のオペレーティングシステム(Linux/Unix、Windows)、行内の複数のパス区切り文字は特別な意味を持たないため、/ path/to/fooおよび/ path // to //// fooは最終的に同じファイルにマップされます。

影響を受ける可能性がある追加の事柄はキャッシングです。ブラウザとサーバーの両方が個別のページをキャッシュするため(キャッシュ設定に応じて)、わずかに異なるURIを介して同じファイルを複数回リクエストすると、キャッシュに影響する可能性があります(サーバーとクライアントの実装によって異なります)。

36
poncha

URLはファイルシステムのパスにマップする必要はありません。したがって、ファイルシステムパスの//が/と同等であっても、すべてのURLに同じことが当てはまるとは限りません。

14
RedGrittyBrick

この質問に対する正しい答えはサーバーの実装によって異なります!です。

序文:URLパス構文を定義するRFC 2396に従って、二重スラッシュは構文的に有効です。 amnが説明するように、これは空のURIセグメントを意味します。ただし、RFC 2396はsyntaxのみを定義し、空のパスセグメントを含むパスのセマンティクスは定義しないため、空のパスのsemanticsを決定するのはサーバーの責任です。

使用しているサーバーソフトウェアスタックについては触れていません。だから、セマンティクスが何であるかについてあなたの想像力を使ってください!

実用的には、日常の意味に関連するいくつかの理由を指摘したいと思います。つまり、ダブルスラッシュは構文的に有効であっても避けなければなりません。

  1. Emptyが有効であることはどういうわけか誰もが期待することではないので、バグを引き起こす可能性があります。そして、今日のサーバーテクノロジは互換性があるかもしれませんが、明日のサーバーテクノロジまたは今日のサーバーテクノロジの次のバージョンは、それをサポートしないことを決定する可能性があります。例:ASP.NET MVC Web APIライブラリは、二重スラッシュでルートテンプレートを指定しようとするとエラーをスローします。

  2. 一部のサーバーは、//をルートパスを示すものとして解釈する場合があります。これは、意図的なものか、バグである可能性があり、おそらくセキュリティバグ、つまりディレクトリトラバーサルの脆弱性です。

  3. これは時々バグであり、セキュリティ上のバグであるため、一部の巧妙なサーバースタックとファイアウォールにはサブストリング「//」が表示され、[このようなバグを悪用するを試みている可能性があると推測します。 403 Forbiddenまたは400 Bad Requestなどを返し、URIの以降の処理を実際に拒否します。

10

関連するpath-absolutenon-terminal の宣言を検討してください "RFC3986:Uniform Resource Identifier(URI):Generic Syntax" (通常、 [〜#〜] abnf [〜#〜] 構文):

path-absolute = "/" [ segment-nz *( "/" segment ) ]

次に、同じドキュメントの数行下のsegment宣言を検討します。

segment       = *pchar

ABNFを読み取ることができる場合、アスタリスク(*)は、次の要素pcharを複数回繰り返してsegmentを構成し、zero回。これを学び、上記のpath-absolute宣言をもう一度読むと、2番目の"/"が繰り返す可能性のある、潜在的に空のsegmentが実装されていることがわかりますindefinitelyしたがって、//////(それ自体がURIを記述するルールの指定に使用されます)の一部として、/(少なくとも1つのpath-absoluteの任意の長さ)のような有効な組み合わせを許可します。

すべてのURLがURIであるため、引用されたRFCに従って、URLは複数の連続したスラッシュが許可されていると結論付けることができます。

しかし、誰もが仕様に従ってURIパーサーをフォローまたは実装しているわけではないため、準拠していないURI/URLパーサーと、これらのコーナーケースが大規模なシステムを破壊するこれらの上にスタックするあらゆる種類のソフトウェアがあるとかなり確信しています。

2
amn

あなたが考慮したいと思うかもしれない1つの事柄はそれがmightが検索エンジンであなたのページ索引付けに影響を与えるということです。 this ウェブページによると、

同じパスが3回繰り返されたURLはGoogleでインデックスに登録されません

彼らが使用する例は:

example.com/path/path/path/

これがexample.com///を使用している場合も同様であることを確認していませんが、SEOの最適化が私のWebサイトにとって重要であるかどうかを確認したいと思います。

彼らは「これは、GoogleがURLトラップにヒットしたと考えているためです」と述べています。他の誰かが確実に答えを知っている場合は、この答えにコメントを追加してください。それ以外の場合は、検討のためにこのケースを含めることが適切だと思いました。

1
Sablefoste

はい、それは間違いなく物事を壊すことができます。

仕様ではhttp://Host/pages/foo.htmlhttp://Host/pages//foo.htmlは異なるURIであると見なされており、サーバーはそれらに異なる意味を自由に割り当てることができます。ただし、ほとんどのサーバーはパス/pages/foo.html/pages//foo.htmlを同じように扱います(基礎となるファイルシステムも同じであるため)。しかし、そのようなサーバーを処理する場合でも、余分なスラッシュが物事を破壊する可能性は簡単にあります。相対URIがサーバーから返される状況を考えます。

http://Host/pages/foo.html  + ../images/foo.png = http://Host/images/foo.png
http://Host/pages//foo.html + ../images/foo.png = http://Host/pages/images/foo.png

その意味を説明させてください。サーバーが次の内容を含むHTMLドキュメントを返すとします。

<img src="../images/foo.png">

ブラウザがそのページを使用して取得した場合

http://Host/pages/foo.html          # Path has 2 segments: "pages" and "foo.html"

ブラウザはロードを試みます

http://Host/images/foo.png          # ok

ただし、ブラウザがそのページを使用して取得した場合

http://Host/pages//foo.html         # Path has 3 segments: "pages", "" and "foo.html"

おそらく同じページが表示されます(サーバーが/pages//foo.html/pages/foo.htmlを区別していない可能性があるためです)が、ブラウザーは誤ってロードを試みます。

http://Host/pages/images/foo.png    # XXX
1
ikegami

たとえば、アプリ内のリソースへのリンクを作成するときに驚くかもしれません。

<script src="mysite.com/resources/jquery//../angular/script.js"></script>

解決しないmysite.com/resources/angular/script.js〜にmysite.com/resources/jquery/angular/script.jsおそらく望んでいないもの

ダブルスラッシュは邪悪です。避けてください。

0
lukyer

あなたの質問は「それは何かを壊すか」です。 URL仕様では、スラッシュを追加できます。 RFCを読まないでください。ブラウザが静かにURLを壊しているかどうかを確認できる簡単な実験があります。

echo '<?= $_SERVER['REQUEST_URI'];' > tmp.php                                   
php -S localhost:4000 tmp.php

MacOS 10.14(18A391)をSafari 12.0(14606.1.36.1.9)とChrome 69.0.3497.100)でテストしたところ、どちらも結果が得られました。

/こんにちは世界

これは、追加のスラッシュを使用するとisがWebアプリケーションに表示されることを示しています。

ダブルスラッシュを使用すると、特定のユースケースが壊れます。これには、単一スラッシュURLを予期しているURLリダイレクト/ルーティング、またはURIを直接分析している他のCGIアプリケーションが含まれます。

しかし、例のように静的コンテンツを提供する通常のケースでは、これでも正しいコンテンツが取得されます。ただし、クライアントは、異なるスラッシュでアクセスされた同じコンテンツに対してキャッシュミスを受け取ります。

0