是斜杠(“/”)等效于HTTP URL的路径部分中的编码斜杠(“%2F”)

时间:2009-12-24 06:52:48

标签: http url encoding

我有一个网站在URL的路径部分(不是查询字符串)中区别对待“/”和“%2F”。根据RFC或现实世界,这是一件坏事吗?

我问,因为我正在使用我正在使用的Web框架(Ruby on Rails)以及下面的层(Passenger,Apache,例如,我必须为Apache启用“ALLOW_ENCODED_SLASHES”)。我现在倾向于完全摆脱编码的斜杠,但我想知道我是否应该提交错误报告,我看到涉及编码斜线的奇怪行为。

至于为什么我首先有编码斜线,基本上我有这样的路线:

:controller/:foo/:bar

其中:foo类似于可以包含斜杠的路径。我认为最简单的事情就是URL escape foo,因此路由机制会忽略斜杠。现在我有疑虑,很明显框架并不真正支持这个,但根据RFC,这样做是不对的?

以下是我收集的一些信息:

RFC 1738(网址):

  

当八位字节由字符表示并且编码时,URL通常具有相同的解释。但是,对于保留字符不是这样:编码为特定方案保留的字符可能会更改URL的语义。

RFC 2396(URIs):

  

这些字符称为“保留”,因为它们在URI组件中的使用仅限于其保留的用途。如果URI组件的数据与保留的目的冲突,则必须在形成URI之前对冲突的数据进行转义。

(这里的转义是指除了编码保留字符以外的其他内容吗?)

RFC 2616(HTTP / 1.1):

  

“保留”和“不安全”集合中的字符(参见RFC 2396 [42])等同于“”%“HEX HEX”编码。

Rails也有this bug report,他们似乎期望编码的斜杠行为不同:

  

是的,我期望得到不同的结果,因为他们指的是不同的资源。

     

它正在根目录中查找文字文件'foo / bar'。非转义版本正在查找目录foo中的文件栏。

从RFC中可以清楚地看出,原始与编码相当于未保留的字符,但保留字符的故事是什么?

6 个答案:

答案 0 :(得分:26)

根据您收集的数据,我倾向于说uri中编码的“/”在application / cgi级别再次被视为“/”。

这就是说,如果你正在使用带有mod_rewrite的apache,它将不会匹配期望对URI的模式和带有编码斜杠的模式。 但是,一旦调用适当的module / cgi / ...来处理请求,它就可以进行解码,例如,检索包含斜杠的参数作为URI的第一个组件。

如果您的应用程序正在使用此数据来检索文件(其文件名包含斜杠),那可能是件坏事。

总而言之,我发现在“/”或“%2F”中看到行为的差异是完全正常的,因为他们的解释将在不同的层次上完成。

答案 1 :(得分:13)

%2F vs /的故事是,根据最初的W3C recommendations,斜线«必须意味着层次结构»

  

示例2

     

URI

     

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

     

     

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

     

不相同,因为第二种情况下编码的斜杠不相同   具有等级意义。

答案 2 :(得分:8)

我还有一个网站,其中包含许多带有urlencoded字符的网址。我发现很多网络API(包括Google网站管理员工具和几个Drupal模块)都会在urlencoded字符上跳过。许多API会在其进程中的某个时刻自动解码URL,然后将结果用作URL或HTML。当我发现其中一个问题时,我通常会对该API的结果进行双重编码(将%2f变为%252f)。但是,这将打破其他不期望双重编码的API,因此这不是一个通用的解决方案。

就个人而言,我正在尽可能多地删除网址中的特殊字符。

另外,我在网址中使用不依赖于urldecoding的ID号:

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

变为:

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

在这种情况下,我的代码只使用12354来查找文章,其余的URL被我的系统忽略(但仍然用于搜索引擎优化。)此外,这个数字应该出现在未使用的URL组件之前。这样,即使%2f被错误解码,网址仍然有效。

另外,请务必使用规范标记,以确保网址错误不会转化为重复内容。

答案 3 :(得分:3)

如果您使用Tomcat,请添加' -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = true'在VM属性中。

https://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#Security

答案 4 :(得分:2)

如果:foo的自然形式包含斜杠,该怎么办?您不希望它 It specifically notes

  

与unix和其他磁盘操作系统文件名约定的相似性应该纯属巧合,不应该用来表明URI应该被解释为文件名。

如果正在构建一个备份程序的在线界面,并希望将路径表示为URL路径的一部分,那么在文件路径中对斜杠进行编码是有意义的,因为不是< / em>实际上是资源层次结构的一部分 - 更重要的是,路由/backups/2016-07-28content//home/dan/以双斜杠丢失文件系统的根目录。正如我所读到的那样,转义斜线是区分的适当方式。

答案 5 :(得分:0)

encodeURI() / decodeURIencodeURIComponent() / decodeURIComponent是处理此问题的实用程序函数。在此处https://stackabuse.com/javascripts-encodeuri-function/

了解更多