我有一个网站在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中可以清楚地看出,原始与编码相当于未保留的字符,但保留字符的故事是什么?
答案 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
的自然形式包含斜杠,该怎么办?您不希望它
与unix和其他磁盘操作系统文件名约定的相似性应该纯属巧合,不应该用来表明URI应该被解释为文件名。
如果正在构建一个备份程序的在线界面,并希望将路径表示为URL路径的一部分,那么在文件路径中对斜杠进行编码是有意义的,因为不是< / em>实际上是资源层次结构的一部分 - 更重要的是,路由。 /backups/2016-07-28content//home/dan/
以双斜杠丢失文件系统的根目录。正如我所读到的那样,转义斜线是区分的适当方式。
答案 5 :(得分:0)
encodeURI()
/ decodeURI
和encodeURIComponent()
/ decodeURIComponent
是处理此问题的实用程序函数。在此处https://stackabuse.com/javascripts-encodeuri-function/