多个正斜杠的URL会导致问题吗?

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

双斜杠对服务器端有影响吗?我有一个解析 URL 的脚本,我想知道如果我将多个斜杠替换为单个斜杠,它是否会导致任何问题(或更改路径)。特别是在服务器端,一些框架如 CodeIgniter 和 Joomla 使用分段 URL 方案和路由。我只想知道它是否会破坏什么。


这是一个有效的路径吗?应该将其视为空路径段吗? - Vamsi Nerella
8个回答

57

HTTP RFC 2396将路径分隔符定义为单斜杠

然而,除非您使用某种URL重写(在这种情况下,重写规则可能会受到斜杠数量的影响),否则URI将映射到磁盘上的路径,但在(大多数?)现代操作系统(Linux / Unix,Windows)中,连续的路径分隔符没有任何特殊含义,因此/path/to/foo和/path//to////foo最终将映射到相同的文件。

可能会受到影响的另一件事是缓存。由于您的浏览器和服务器根据其缓存设置缓存各个页面,因此通过稍微不同的URI多次请求同一文件可能会影响缓存(取决于服务器和客户端实现)。


1
你需要查看你引用的文档中的第3.3节(或者RFC3986,它已经废弃了该文档,但在这里讨论的行为上达成了一致),其中通过ABNF指定了path_segments至少由一个segment令牌组成,而segment本身可以是空长度。这意味着像//这样的字符序列在URI中是完全有效的。 - Armen Michaeli
2
@amn 这是有效的,没有问题。但问题是它是否会破坏任何东西。如果您使用URL重写(例如),它可能会破坏某些内容。 - poncha
30
这是一个很好的回答!可惜它是 https:///stackoverflow.com////////a/////10161264/////6618577 的复制品... - Aric
3
"除非您使用某种URL重写,否则这也会影响相对URL。http://host/a/b/c/d + ../../e = http://host/a/e,而http://host/a/b/c//d + ../../e = http://host/a/b/e。" - ikegami
@ikegami 确实 ;) 很好的发现 - poncha

18

这个问题的正确答案是它取决于服务器的实现

前言:根据定义URL路径语法的RFC 2396,双斜杠在语法上是有效的。正如amn所解释的那样,它因此意味着一个空的URI段。但请注意,RFC 2396仅定义了路径的语法,包括空路径段的语义,因此由您的服务器决定空路径的语义。

您没有提到您正在使用的服务器软件堆栈,也许您甚至正在自己开发?因此,请想象一下语义可能是什么!

实际上,我想指出一些日常语义相关的原因,即使它们在语法上是有效的,您也应该避免使用双斜杠:

  1. 当不是每个人都认为空值应该是有效的时,它可能会导致错误!即使您今天的服务器技术与之兼容,但您明天的服务器技术或今天的服务器技术的下一个版本可能不兼容。(例如:ASP.NET MVC Web API库在尝试指定具有双斜杠的路由模板时会抛出错误。)

  2. 一些服务器可能会将//解释为表示根目录。这可能会成为目录遍历漏洞 - 然后通常是安全漏洞(查找“目录遍历漏洞”)。

  3. 因为它有时是一个错误和安全漏洞,所以防御性设计的服务器堆栈和防火墙将假定任何传入请求中的子字符串'//'都是可能的尝试利用漏洞,因此他们将通过返回403 Forbidden404 Not Found400 Bad Request来阻止它 - 而不会实际进一步处理URI或请求。


16

URL与文件系统路径不必一一对应。因此,即使在文件系统路径中//等同于/,也不能保证所有URL都是如此。


2

考虑在“RFC3986:统一资源标识符(URI):通用语法”中声明相关的path-absolute 非终端符号(通常使用ABNF语法进行指定):

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

那么请看同一文档中稍后几行的segment声明:
segment       = *pchar

如果您能够阅读ABNF,那么星号(*)表示以下元素pchar可以重复多次以组成一个segment,包括零次。通过学习这一点并重新阅读上面的path-absolute声明,您可以看到一个可能为空的segment意味着第二个"/"可能会无限重复,因此允许像//////(至少一个/的任意长度)这样的有效组合作为path-absolute的一部分(它本身用于指定描述URI的规则)。
由于所有URL都是URI,因此我们可以得出结论,根据引用的RFC,是允许URL中存在多个连续的正斜杠的。
但并不是每个人都遵循或实现符合规范的URI解析器,因此我相当确定存在不符合规范的URI / URL解析器和各种在其之上堆叠的软件,其中这些边角情况会破坏更大的系统。

3
你的回答仅说明http://host/a////b是一个有效的URI,但这不是OP所问的。事实上,您引用的RFC本身就说它们不等同。事实上,即使http://host/a////b是有效的,也不能认为它等同于http://host/a/b - ikegami
问题不在于你引用的两个URL是否等效。问题是询问多个正斜杠的URL是否会破坏任何东西,我的回答基本上是“实际上可能会,但从理论上讲,它们不应该,因为多个正斜杠符合规范的规范URL”。 - Armen Michaeli
3
再次强调,它是一个有效的URI这一事实并不重要。http://foo/也是一个有效的URI,但如果你使用它而不是http://stackoverflow.com,它肯定会破坏一些东西。由于你的回答只是展示了URI是有效的,它并没有回答问题。 - ikegami

1
是的,它肯定可以破坏事情。
规范认为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

你可能需要考虑的一件事是,这可能会影响到搜索引擎对你页面的索引。根据this网页所述:

重复3次相同路径的URL将不会被Google索引

他们使用的例子是:

example.com/path/path/path/

我不确定如果您使用example.com///是否也是如此,但如果SEO优化对我的网站至关重要,我肯定想找出答案。
他们提到:“这是因为Google认为它已经陷入了URL陷阱。” 如果有其他人确切知道答案,请在此回答中添加评论;否则,我认为包括这个案例是值得考虑的。

0

例如,在为应用程序中的资源构建链接时,您可能会感到惊讶。

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

不会解析为 mysite.com/resources/angular/script.js而是 mysite.com/resources/jquery/angular/script.js这可能不是您想要的

双斜杠很麻烦,请尽量避免使用。


-2

你的问题是“它是否会破坏任何东西”。就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,两者都得到了以下结果:

/hello//world

这表明使用额外的斜杠对Web应用程序是可见的。

在使用双斜杠时,某些用例将会出现问题。这包括期望单斜杠URL或直接分析URI的其他CGI应用程序的URL重定向/路由。

但对于提供静态内容的正常情况,例如您的示例,这仍将获得正确的内容。但客户端将针对使用不同斜杠访问的相同内容获得缓存未命中。


澄清了关于哪些部分是损坏的和哪些部分不是损坏的具体答案。 - William Entriken
关于“this will still get the correct content”,不,它不会,如果所提供的页面包含相对路径的脚本、图像等。 - ikegami
限定词“正常情况下提供静态内容,例如您的示例”不包括您示例中带有..的双斜杠的特殊情况。 - William Entriken
2
好的。谁说在http://url/a//b中引用../xyz以获取http://url/a/xyz不是预期行为? - William Entriken
总结:具有斜杠运行的URI与那些斜杠运行折叠(s | / + | / | g)的URL不同。很可能您的服务器将提供相同的文件。您需要对相对URL的影响负责。 - William Entriken
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接