这个是一个快速的:
cookie名称和值中允许的字符是什么?它们与URL或某些常见子集相同吗?
我要问的原因是,我最近发现了一些奇怪的行为,其中包含-名称中的cookie,我只是想知道它是否是浏览器特定的,或者我的代码是否有问题.
bob*_*nce 372
这个是一个快速的:
你可能认为它应该是,但实际上根本不是!
cookie名称和值中允许的字符是什么?
根据古老的Netscape cookie_spec,整个NAME=VALUE字符串是:
一系列字符,不包括分号,逗号和空格.
所以-应该工作,而且我在这里的浏览器似乎没问题; 你在哪里遇到麻烦?
通过以上含义:
=是合法的,但可能含糊不清.浏览器总是=在字符串中的第一个符号上拆分名称和值,因此实际上您可以=在VALUE中放置符号而不是NAME.什么没有提到,因为Netscape在编写规范时很糟糕,但似乎一直受到浏览器的支持:
NAME或VALUE可能是空字符串
如果=字符串中根本没有符号,浏览器会将其视为具有空字符串名称的cookie,即Set-Cookie: foo与...相同Set-Cookie: =foo.
当浏览器输出一个空名称的cookie时,它们会省略等号.所以Set-Cookie: =bar忘了Cookie: bar.
名称和值中的逗号和空格实际上似乎有效,尽管修剪了等号周围的空格
控制字符(\x00以\x1F加\x7F)不允许
没有提到的和浏览器完全不一致的是非ASCII(Unicode)字符:
所以在实践中你根本不能在cookie中使用非ASCII字符.如果您想使用Unicode,控制代码或其他任意字节序列,cookie_spec要求您使用您自己选择的ad-hoc编码方案,并建议URL编码(由JavaScript生成encodeURIComponent)作为合理的选择.
就实际标准而言,已经有一些尝试来编纂cookie行为,但到目前为止还没有人真正反映现实世界.
RFC 2109试图编写和修复原始的Netscape cookie_spec.在该标准中有更多的特殊字符都不允许,因为它使用RFC 2616级的令牌(一个-是仍然允许存在),并且只有该值可以在一个引用字符串与其他字符来指定.没有浏览器实现过限制,引用字符串和转义的特殊处理,或者本规范中的新功能.
RFC 2965是另一回事,整理2109并在'版本2 cookie'方案下添加更多功能.也没有人实施任何一项.此规范具有与早期版本相同的令牌和引用字符串限制,并且同样是一堆废话.
RFC 6265是一个HTML5时代的尝试,以清理历史混乱.它仍然与现实完全不符,但它比早期的尝试要好得多 - 它至少是浏览器支持的适当子集,不会引入任何应该工作但不能工作的语法(就像之前的引用字符串一样) .
在6265中,cookie名称仍被指定为RFC 2616 token,这意味着您可以从alphanums中选择以及:
!#$%&'*+-.^_`|~
Run Code Online (Sandbox Code Playgroud)
在cookie值中,它正式禁止(通过浏览器过滤)控制字符和(不一致地实现的)非ASCII字符.它保留了cookie_spec对空格,逗号和分号的禁止,以及与实际实现早期RFC的任何可怜的白痴的兼容性,它还禁止反斜杠和引号,除了包含整个值的引号(但在这种情况下,引号仍然被认为是值,而不是编码方案).因此,您可以使用alphanums plus:
!#$%&'()*+-./:<=>?@[]^_`{|}~
Run Code Online (Sandbox Code Playgroud)
在现实世界中,我们仍在使用原始和最差的Netscape cookie_spec,因此使用cookie的代码应该准备好遇到几乎任何东西,但是对于生成cookie的代码,建议坚持使用RFC 6265中的子集.
ste*_*hen 28
在ASP.Net中,您可以System.Web.HttpUtility在写入cookie之前安全地对cookie值进行编码,并在读取时将其转换回原始格式.
// Encode
HttpUtility.UrlEncode(cookieData);
// Decode
HttpUtility.UrlDecode(encodedCookieData);
Run Code Online (Sandbox Code Playgroud)
这将停止&符号和等号,在将值写入cookie时将值拆分为一堆名称/值对.
Jam*_*low 17
我认为这通常是浏览器特定的.为了安全起见,base64编码一个JSON对象,并将所有内容存储在其中.这样你只需解码它并解析JSON.base64中使用的所有字符都可以与大多数(如果不是全部)浏览器一起使用.
mom*_*omo 10
在这里,尽可能少的话.专注于不需要转义的角色:
饼干:
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!#$%&'()*+-./:<>?@[]^_`{|}~
Run Code Online (Sandbox Code Playgroud)
对于网址
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789.-_~!$&'()*+,;=:@
Run Code Online (Sandbox Code Playgroud)
用于饼干和网址(交叉口)
abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!$&'()*+-.:@_~
Run Code Online (Sandbox Code Playgroud)
这就是你的回答.
请注意,对于cookie,=已被删除,因为它通常用于设置cookie值.
对于网址,保留了=.交叉点显然没有.
var chars = "abdefghijklmnqrstuvxyz"; chars += chars.toUpperCase() + "0123456789" + "!$&'()*+-.:@_~";
Run Code Online (Sandbox Code Playgroud)
结果是逃避仍然发生和意外发生,特别是在Java cookie环境中,如果遇到最后一个字符,cookie用双引号括起来.
所以为了安全起见,只需使用A-Za-z1-9即可.这就是我要做的.
较新的rfc6265于2011年4月发布:
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
cookie-pair = cookie-name "=" cookie-value
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
Run Code Online (Sandbox Code Playgroud)
如果你期待@bobince的回答你会看到更新的限制更严格.
| 归档时间: |
|
| 查看次数: |
145830 次 |
| 最近记录: |