Cookie中允许的字符

Esk*_*sko 290 cookies

这个是一个快速的:

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)字符:

  • 在Opera和Google Chrome中,它们使用UTF-8编码为Cookie标头;
  • 在IE中,使用机器的默认代码页(特定于语言环境,从不使用UTF-8);
  • Firefox(以及其他基于Mozilla的浏览器)自己使用每个UTF-16代码点的低字节(因此ISO-8859-1可以,但其他任何东西都被破坏了);
  • Safari只是拒绝发送任何包含非ASCII字符的cookie.

所以在实践中你根本不能在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中的子集.

  • [RFC 6265](https://www.ietf.org/rfc/rfc2616.txt) 将标记定义为 `1*&lt;除 CTL 或分隔符之外的任何 CHAR&gt;`,分隔符为 `(`、`)`、`&lt;` , `&gt;`, `@`, `,`, `;`, `:`, ``\``, `"`, `/`, `[`, `]`, `?`, `=` 、 `{`、`}`、`SP` 和 `HT`,因此 cookie 名称应该是字母加上 ``!#$%&amp;'*+-.?^_`|~`` (5认同)

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时将值拆分为一堆名称/值对.

  • 请注意,在存储身份验证 cookie 时,asp.net 在内部使用十六进制编码而不是 UrlEncode。https://referencesource.microsoft.com#System.Web/Security/FormsAuthentication.cs,507f5d4465177372 所以可能在某些情况下url编码不会切断它? (2认同)

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即可.这就是我要做的.

  • @Loc 超过 3 小时的试验和检查。 (2认同)

gav*_*koa 8

较新的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的回答你会看到更新的限制更严格.

  • 您在上面复制的铁路图中的勘误表以及第 5.4 节中的文本... 该图以 `; 分隔。OWS`,文本需要文字`; `(带空格)。 (2认同)

小智 6

你不能把";" 在cookie的value字段中,将设置的名称是";"之前的字符串 在大多数浏览器...