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

Tim*_*nen 28 url multidimensional-array query-string

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

http://example.com?abc[]=123&abc[]=456
Run Code Online (Sandbox Code Playgroud)

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

我想听听第二个意见.

Dav*_*ian 27

答案并不简单.

以下内容摘自RFC 3986的3.2.2节:

由Internet协议文字地址版本6
[RFC3513]或更高版本标识的主机通过将IP文本
括在方括号("["和"]")中来区分.这是
URI语法中唯一允许使用方括号字符的位置.

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

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

  1. 语法组件

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

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

所以"查询"是"URI"的一个组成部分.

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

2.2.保留字符

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

  reserved    = gen-delims / sub-delims

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

  sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="
Run Code Online (Sandbox Code Playgroud)

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

URI生成应用程序应对
与保留集中的字符对应的数据八位字节进行百分比编码,除非
URI方案明确允许这些字符表示该
组件中的数据.如果在URI组件中找到保留字符且
该字符不知道分隔角色,则必须将其
解释为表示与
US-ASCII中该字符的编码对应的数据八位字节.

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

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

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

  • “如果不是经过方括号编码的,则方括号可以出现在查询字符串中,除非不是” xD。非常好的答案。 (2认同)
  • 这是一个很棒的答案,但它没有考虑到WHATWG Url规范.请参阅下面的答案. (2认同)

And*_*ahl 11

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

*( pchar / "/" / "?" )
Run Code Online (Sandbox Code Playgroud)

从同一RFC的附录A:

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

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

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

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

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

  • 你当然是对的,但请帮我解释一下.你提供的摘录是不完整的,这里从未重新提及"保留".所以定义没有这样的意义.当我读到它时,方括号被定义为具有特殊含义的保留字符(不确定是哪个),因此如果要表达该含义,则不应转义它们.如果你逃避它,你只需转移一个包含方括号的字符串作为参数的值.所以我问自己:嗯,实际上,方括号的意思是在网址中保留字符? (3认同)
  • 因为IPv6字面量仅适用于主机部分http:// [1080:0:0:0:8:800:200C:417A] / index.html`,因此我想它们并不适用在查询字符串中使用时需要转义 (2认同)

Eth*_*han 6

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,它没有对百分比编码这些字符做任何参考。