URL中保留的分号是什么?

时间:2010-01-29 17:31:12

标签: url uri character rfc3986

RFC 3986 URI: Generic Syntax规范将分号列为保留(sub-delim)字符:

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

“;”的保留目的是什么? URI中的分号?就此而言,其他子delim的目的是什么(我只知道“&”,“+”和“=”的目的)?

6 个答案:

答案 0 :(得分:35)

第3.3节末尾有一个解释。

  

除了点数段   分层路径,路径段   通用认为不透明   句法。 URI生成应用程序   经常使用保留字符   允许在一个细分中划分   特定计划或   取消引用处理程序,具体   子。例如,   分号(“;”)和等号(“=”)   经常使用保留字符   划分参数和参数   适用于该细分的价值。   逗号(“,”)保留字符是   经常用于类似目的。   例如,一个URI生成器可能   使用诸如“name; v = 1.1”之类的段   表示对1.1版的引用   “名字”,而另一个可能   使用诸如“name,1.1”之类的段   表示相同。参数类型   可以通过特定方案来定义   语义,但在大多数情况下   参数的语法特定于   URI的实现   解除引用算法。

换句话说,它是保留的,以便想要URL中某些分隔列表的人可以安全地使用;作为分隔符,即使部分包含;,只要内容是百分比编码的。换句话说,你可以这样做:

foo;bar;baz%3bqux

并将其解释为三个部分:foobarbaz;qux。如果分号不是保留字符,则;%3b将是等效的,因此URI将被错误地解释为四个部分:foobar,{{ 1}},baz

答案 1 :(得分:7)

如果你回到规范的older versions,意图会更清楚:

  path_segments = segment *( "/" segment )
  segment       = *pchar *( ";" param ) 
  

每个路径段可以包括a      参数序列,由分号“;”表示字符。

我相信它起源于FTP URI s。

答案 2 :(得分:5)

Section 3.3 covers this - 这是一个不透明的分隔符,如果方便的话,URI生成的应用程序可以使用:

  

除了点数段   分层路径,路径段   通用认为不透明   句法。 URI生成应用程序   经常使用保留字符   允许在一个细分中划分   特定计划或   取消引用处理程序,具体   子。例如,   分号(“;”)和等号(“=”)   保留字符经常用于   分隔参数和参数   适用于该细分的价值。该   逗号(“,”)保留字符是   经常用于类似目的。对于   例如,一个URI生成器可能使用a   段如“name; v = 1.1”到   表示对1.1版本的引用   “名字”,而另一个可能使用   段如“名称,1.1”表示   相同。参数类型可以是   由特定于方案的语义定义,   但在大多数情况下,a的语法   参数是特定的   URI的实现   解除引用算法。

答案 3 :(得分:4)

目前的使用范围有一些有趣的约定。这些说到何时使用分号或逗号。从“RESTful Web Services”一书中可以看出:

  

使用标点符号在同一层次结构中分隔多个数据。当项目的顺序很重要时使用逗号,...当订单无关紧要时使用分号。

答案 4 :(得分:2)

自2014年以来,已知路径段对Reflected File Download attacks有贡献。我们假设我们有一个易受攻击的API,它反映了我们发送给它的任何内容(网址显然是真实的,现在已修复):

https://google.com/s?q=rfd%22||calc||

{"results":["q", "rfd\"||calc||","I love rfd"]}

现在,这在浏览器中是无害的,因为它的JSON不会被渲染,但浏览器宁愿将响应下载为文件。现在,路径段为攻击者提供了帮助:

https://google.com/s;/setup.bat;?q=rfd%22||calc||

分号(;/setup.bat;)之间的所有内容都将发送到Web服务,而是浏览器会将其解释为文件名...以保存API响应。现在,将下载并运行名为setup.bat的文件,而不会询问运行从Internet下载的文件的危险(因为它的名称中包含单词"setup")。内容将被解释为Windows批处理文件,并将运行calc.exe命令。

预防:

  • 清理您的API输入(在这种情况下,他们应该只允许使用字母数字);逃避是不够的
  • 在不会呈现的API上添加Content-Disposition: attachment; filename="whatever.txt";谷歌错过了实际使攻击更容易的filename部分
  • 向API回复添加X-Content-Type-Options: nosniff标头

答案 5 :(得分:0)

我发现了以下用例:

它是HTML实体的最终字符:
https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references

  

在HTML或XML中使用其中一个字符实体引用   文件,输入&符号,后跟实体名称和a   分号,例如&对于&符号("&")。

Apache Tomcat 7(或更新的版本?!)将其标记为path parameter
https://superevr.com/blog/2011/three-semicolon-vulnerabilities

  

Apache Tomcat是支持" Path的Web服务器的一个示例   参数&#34 ;.路径参数是文件名后的额外内容,   用分号分隔。分号后的任意内容   不会影响Web浏览器的登录页面。这意味着   http://example.com/index.jsp;derp仍将返回index.jsp,而不是   一些错误页面。

URI方案将MIME和数据拆分为:
https://en.wikipedia.org/wiki/Data_URI_scheme

  

它可以包含一个可选的字符集参数,与之分开   前面的部分用分号(;)。

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

IIS5和IIS6中存在一个错误,可以绕过文件上传限制:
https://www.owasp.org/index.php/Unrestricted_File_Upload

  

将文件扩展名列入黑名单可以绕过以下保护:...   通过在禁止扩展名后添加分号字符和   在允许的之前(例如&#34; file.asp; .jpg&#34;)

<强>结论:
不要在URL中使用分号,否则它们可能会意外地产生HTML实体或URI方案。