在URL查询字符串中使用方括号的数组语法是否有效?

时间:2012-07-15 07:43:51

标签: url multidimensional-array query-string

在URL查询字符串中使用多维数组合成器实际上是安全/有效吗?

http://example.com?abc[]=123&abc[]=456

它似乎适用于每个浏览器,我一直认为可以使用,但在本文中评论不是:http://www.456bereastreet.com/archive/201008/what_characters_are_allowed_unencoded_in_query_strings/#comment4

我想听听第二个意见。

6 个答案:

答案 0 :(得分:24)

答案并不简单。

以下内容摘自RFC 3986的3.2.2部分:

  

由Internet协议字面地址标识的主机,版本6
  [RFC3513]或更高版本,通过附上IP文字来区分   在方括号内(“[”和“]”)。这是唯一的地方   URI语法中允许使用方括号字符。

这个似乎通过断言地在URI中的其他任何地方都不允许使用方括号来回答这个问题。但是方括号字符和百分比编码的方括号字符之间存在差异。

以下内容摘自RFC 3986第3部分的开头:

  
      
  1. 语法组件

         

    通用URI语法由分层序列组成   组件称为方案,权限,路径,查询和
      片段。

         

    URI = scheme“:”hier-part [“?”查询] [“#”片段]

  2.   

所以“查询”是“URI”的一个组成部分。

以下内容摘自RFC 3986的第2.2节:

  

2.2。保留字符

     

URI包括由
分隔的组件和子组件   “保留”集中的字符。这些字符称为
  “保留”,因为它们可能(或可能不)被定义为分隔符   通用语法,每种方案特定的语法,或由   URI的解除引用算法的特定于实现的语法   如果URI组件的数据与保留的数据发生冲突   角色作为分隔符的目的,那么冲突的数据必须是   在URI形成之前进行百分比编码。

  reserved    = gen-delims / sub-delims

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

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

因此方括号可能出现在查询字符串中,但前提是它们是百分比编码的。除非它们不是,将在2.2节进一步解释:

  

生成URI的应用程序应该对数据八位字节进行百分比编码   对应于保留集中的字符,除非这些字符为   URI方案特别允许表示该中的数据   零件。如果在URI组件中找到保留字符,则为   没有对该角色的分界角色,那么它必须是
  解释为表示与该对应的数据八位字节   字符在US-ASCII中的编码。

因为方括号只允许在“主机”子组件中使用,所以它们“应该”在其他组件和子组件中进行百分比编码,在本例中为“查询”组件,除非RFC 3986明确允许未编码的方括号表示查询组件中的数据,但不是。

但是,如果“URI生成应用程序”无法执行“应该”执行的操作,则通过在查询中保留未编码的方括号,则URI的读者不会完全拒绝URI。相反,方括号应被视为属于查询组件的数据,因为它们不用作该组件中的分隔符。

这就是为什么,例如,当PHP接受未编码和百分比编码的方括号作为查询字符串中的有效字符时,它不违反RFC 3986,甚至为它们分配特殊用途。但是,似乎试图通过不使用方括号编码百分比来利用这个漏洞的作者违反了RFC 3986.

答案 1 :(得分:11)

根据RFC 3986,URL的Query component具有以下语法:

*( pchar / "/" / "?" )

来自同一RFC的appendix A

pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
[...]
pct-encoded   = "%" HEXDIG HEXDIG

unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
[...]    
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
             / "*" / "+" / "," / ";" / "="

我对此的解释是,任何不是:

 ALPHA / DIGIT / "-" / "." / "_" / "~" / 
     "!" / "$" / "&" / "'" / "(" / ")" / 
     "*" / "+" / "," / ";" / "=" / ":" / "@"

...应该是pct编码的,即百分比编码。因此,[]应按百分比编码,以遵循RFC 3986。

答案 2 :(得分:4)

David N. Jafferian的回答太棒了。我只想添加一些更新和实用说明:

  1. 多年来,在向服务器提交请求时,每个浏览器都在未编码的查询字符串中留下了方括号。 (资料来源:https://bugzilla.mozilla.org/show_bug.cgi?id=1152455#c6)。因此,我认为网络的很大一部分已经依赖于这种行为,这使得它极不可能改变。

  2. 我对WHATWG URL标准的阅读,至少出于网络目的,可以被视为取代RFC 3986,它将这种不编码[]的行为编成法典。查询字符串。我相信相关部分是:https://url.spec.whatwg.org/#query-state,它没有提供关于编码这些字符的百分比的参考。

答案 3 :(得分:1)

当我不得不传递一个数组时,我总是有诱惑去寻找那种查询,但我却远离了它。原因是:

  • 未在RFC中定义。
  • 不同的语言可能会有不同的解释。

您有几个传递数组的选项:

  • 编码数组的字符串表示形式(JSON可能是?)
  • 有“val1 = blah& val2 = blah& ...”之类的参数或类似的东西。

如果你确定你使用的语言,你可以(安全地)找到你所拥有的那种查询字符串(只是你需要%-encode [])。

答案 4 :(得分:1)

我的理解是方括号不是一流的公民。这是引用: http://tools.ietf.org/html/rfc1738

  

其他字符不安全,因为网关和其他传输   已知代理有时会修改这些字符。这些   字符是“{”,“}”,“|”,“\”,“^”,“〜”,“[”,“]”和“`”。

答案 5 :(得分:1)

理想情况下,我真的很想对Ethan's answer进行评论,但是没有足够的声誉来做到这一点。

我不确定此处是否引用了WHATWG URL标准的相关部分。我认为正确的部分可能在有效的URL-query string的定义中,它被描述为由URL units组成,而它们本身是由URL code pointspercent-encoded bytes组成的。方括号在URL代码点内列出,因此属于百分比编码的字节类别。

因此,为回答原始问题,URL的查询部分内的多维数组语法(即,使用方括号表示数组索引)是有效的,假设方括号是百分比编码的(表示为[[]为%5B,[]为%5D)。