HTTP 状态管理机制——RFC6265翻译文档



此文档为pcn-cad实验室宋老师所指导的林昌伟、赵雪君所翻译,如有纰漏,望大家多多指教


因特网工程任务组(IETF

文档:6265

取代文档:2965

类别:标准化过程

ISSN2070-1721

 

HTTP 状态管理机制


摘要

本文档规定了HTTP cookie 以及Set-Cookie 头字段。这些头字段可以被HTTP服务器用来在HTTP客户端存储状态(被称为cookie),以此让服务器在基本为无状态的HTTP协议上保持有状态会话。尽管cookies会存在安全性和私密性等历史性的隐患,cookie 以及Set-Cookie 头字段在因特网上广泛地使用。这份文件取代RFC 2965

关于下段备忘

这是因特网标准跟踪文档。

 

这份文档是因特网工程任务组(IETF)的产物。它代表了IETF组织的共识。它接受了公共审查以及已被互联网工作任务组(IESG)批准出版。关于互联网标准的进一步信息可以在RFC5741 的第二部分获得。

 

本文档的当前状态的信息,任何勘误表,以及如何去获得信息回馈可以在

http://www.rfc-editor.org/info/rfc6265获得

版权声明

版权所有(c 2011 IETF 官方以及被确认为作者的个人,保留所有版权。

 

这份文档受到BCP 78 以及 IETF 官方与IETF文档相关联的法律条款管制

(http://trustee.ietf.org/license-info)自本文档的发表之日生效。请仔细阅读这些文档,正如第四节所描述的官方法律条款描述,从该文档提取的代码组件必须包含简化的BSD许可文档;并且这些代码被提供不包含保证,正如简化的BSD许可文档所描述的那样。

 

这份文档可能包含从IETF文档或者截止20081110日可获得的IETF公开投稿。在一些材料上的个人版权可能并没有授予IETF官方权利在IETF标准流程以外进行修改。没有从在这些材料上的版权个体处获得足够的许可,这份文档可能不能在IETF标准流程外进行修改,以及相关的衍生作品不能在IETF标准流程外进行创作,除去RFC出版的格式化需要以及将这份文档翻译为除去英语外的其他语言。

 

目录

1简介···························································································································· 3

2.概念···························································································································· 4

2.1适用性标准········································································································ 4

2.2语法符号··········································································································· 4

2.3.术语·················································································································· 5

3···························································································································· 5

3.1.示例·················································································································· 5

4.服务器要求················································································································· 7

4.1Set-Cookie·········································································································· 7

4.1.1.语法········································································································ 7

4.1.2.语义(非规范)······················································································· 8

4.2Cookie·············································································································· 10

4.2.1.语法······································································································· 10

4.2.2.语义······································································································· 10

5.客户端要求·················································································································· 10

5.1.子组件算法········································································································ 11

5.1.1.日期········································································································· 11

5.1.2.规范化的主机名························································································ 12

5.1.3.域匹配······································································································ 13

5.1.4.路径和路径匹配························································································ 13

5.2.Set-Cookie头字段································································································ 14

5.2.1.过期(Expires)属性················································································· 15

5.2.2.最大缓存时间(Max-Age)属性································································ 16

5.2.3.域(Domain)属性···················································································· 16

5.2.4.路径(Path)属性····················································································· 16

5.2.5.安全(Secure)属性·················································································· 17

5.2.6.HttpOnly属性···························································································· 17

5.3.存储模型············································································································ 17

5.4.Cookie头部········································································································· 20

6. 实施注意事项············································································································· 21

6.1.限制··················································································································· 21

6.2.应用程序接口····································································································· 22

6.3.IDNA依赖和迁移································································································ 22

7. 隐私注意事项············································································································· 22

7.1.第三方Cookies···································································································· 22

7.2.用户控件············································································································ 23

7.3.到期时间············································································································ 23

8. 安全注意事项············································································································· 23

8.1.概述··················································································································· 23

8.2.外界权力············································································································ 24

8.3.明文··················································································································· 24

8.4.会话标识符········································································································ 25

8.5.弱保密性············································································································ 25

8.6.弱诚信性············································································································ 26

8.7.DNS依赖············································································································ 26

9. IANA注意事项············································································································· 26

9.1.Cookie················································································································ 26

9.2.Set-Cookie··········································································································· 27

9.3.Cookie2··············································································································· 27

9.4.Set-Cookie2········································································································· 27

10. 参考························································································································· 27

10.1.引用标准········································································································ 28

10.2.参考文献········································································································ 28

附录A.致谢·················································································································· 28

 

 

1简介

这份文档定义了HTTP cookie以及Set-Cookie头字段。通过Set-Cookie头字段,HTTP服务器可以向用户客户端传递cookie[名称,一组值]以及相关的元数据。当用户客户端向服务器发出后续请求,用户客户端通过元数据以及其他信息去决定向Cookie头部返回的名称以及值。

 

尽管它们表面单一,cookies有许多复杂之处。比如说,当服务器向客户端发送cookie时,显示每一个cookie的适用范围。这适用范围表明用户客户端应该返回cookie的最长时间段,服务器,服务器向客户端返回cookie的最长时间段以及可适用cookieURI方案。

 

基于历史性的原因,cookie包含很多安全以及隐私的隐患。比如说,服务器可以表明一个给定的cookie打算“安全”连接,不打算在面对活跃的网络攻击者时提供完整性。同样,一个指定主机的cookie为该主机上的所有端口共享,即便是通常为网络浏览器所用的“同源政策”通过不同的端口隔离内容检索。

 

这份详述有两种受众:生成cookie的服务器的开发者以及消耗cookie的客户端的开发者。

为了极大化用户客户端的互操作性,当服务器生成cookies时,服务器“应该”限制到在第四部分中简况表现良好的客户端。

 

用户客户端“必须“添加更为书面化的在第五部分定义过的处理条例,以此去极大化在已存在在第四部分中简况表现不良好的服务器间的互用性。

 

这份文档指定了这些头部在因特网上使用的语法和语义。特别地,除去那些目前正在使用的语法和语义,这份文档不能生成新的语法或者语义。在第四部分所提供的cookie生成的推荐展现了在现今服务器行为下一个偏爱的子集,以及在第五部分的更为书面化的cookie处理算法不能推荐现今所有的语法以及语义多样性。在一些重要的方面,一些已存在的软件不同于推荐的条款,这份文档包含了一份注解来解释这些不同。

 

这份文档以前,至少存在三种cookies的解释:所谓的“网景cookie详述”[网景]RFC 2109 [RFC 2109]以及RFC 2965 [RFC 2965]。然而,上述任何一个文档都没有阐述为何cookiecookie设置头部确实在因特网上使用(关于历史原因请参考[Kri 2001])。在与以前的HTTP状态管理机制的IETF详述的相关关系中,这份文档请求以下行为:

 

  1. 改变[RFC 2109](已经为[RFC 2965]所废止)的历史状态;

     

  2. 改变[RFC 2965]的历史状态;

 

  1. 表明[RFC 2965]已经被这份文档所废止。

 

特别地,从历史上移除以及废止[RFC 2965],这份文档反对Cookie2以及Set-Cookie2头字段的使用。

 

2.概念

2.1.适用性标准

 

这份文档中的关键词 “必须”、“必须不”、“ 被要求”、“将会”、“将会不”、“应该”、“应该不”、“建议”、“可能”、“可选”应该符合[RFC 2119]中的解释。

 

要求阐释在算法的必要部分应该阐述介绍算法中使用的关键字(“MUST”“MUST NOT”“REQUIRED”等)的意思。

 

阐释算法或者特定的步骤的要求一致性可以为任何行为所补充,只要最后的结果是同等。特别地,定义在这详述的算法应该简单易懂,且不该是形式上的。

 

2.2.语法符号

 

这份详述使用了扩充巴科斯-诺尔形式(ABNF)关于[RFC 5234]的注解。

 

接下来的核心规则为参考所包含,正如定义在[RFC 5234],附录B.1:

ALPHA (字母)

CR (回车)

CRLF(CR LF)

CTLs (控制字符)

DIGIT (十进位 0-9)

DQUOTE (双引号)

HEXDIG (十六进制0-9/A-F/a-f), LF (换行)

NUL (空八隅体)

OCTET (除去NUL的任意八位序列数据)

SP (空格键)

HTAB(水平制表符)

CHAR (除去NUL任何 [USASCII] 字符)

VCHAR (如何可显[USASCII]字符)

WSP (空格).

 

The OWS (可选空白) 规则被用在0及其以上更多的线性空白键字符“可能”出现:

OWS = *( [ obs] WSP )

; "可选"空白

obs-fold = CRLF

OWS “应该”既不被产生或者被生成单一SP字符。

 

2.3.术语

 

术语:用户,客户端,委托人,服务器,搭理人以及初始服务器拥有与HTTP/1.1 详述([RFC 2616]中的第1.3部分)相同的意义。

 

请求主机是为用户客户端所知晓的主机的名称,用户客户端从这里发送HTTP请求或者收取HTTP响应(此外,主机的名称使得发送相应一直的HTTP请求)。

 

术语请求uri定义在[RFC 2616]中的第5.1.2部分。

 

八隅体的两种序列被称为非敏感实例相互匹配当且仅当他们在i条件下等价;;ascii码图排序定义在 [RFC4790]

术语流意味非NUL 八隅体的一个序列。

 

3.概述

这一部分概括初始服务器给用户客户端发送状态信息以及用户客户端向初始服务器返回状态信息的方式。

 

为了保存状态,初始服务器包含一个在HTTP响应中的Set-cookie头部。在接下来的请求中,用户客户端向初始服务器返回一个Cookie请求头部。Cookie头部包含用户客户端所有之前收到的Set-Cookie头部的Cookies。初始服务器自由地忽略Cookie头部或者出于定义应用的目的使用内容。

 

初始服务器“可能”传送一个任意响应的Set-Cookie响应头部。用户客户端“可能”忽略包含在100-层状态码的响应中的Set-Cookie头部,然而“必须”处理包含在其他响应(包括400500层状态码的响应)中的Set-Cookie头部。初始服务器可以在单个响应中包含多重Set-Cookie头部状态。一个Cookie或者Set-Cookie头部状态的显现并不能从存储以及反复使用响应中排除HTTP缓存。

 

初始服务器“应该不”合并多重Set-Cookie 头部状态成一个单一的头部状态。通常合并HTTP头部状态(定义在[RFC 2616])的机制可能会改变Set-Cookie头部状态的语义,因为%x2C(",")字符被Set-Cookie用来与这样的合并竞争。

 

3.1.例子

 

使用Set-Cookie头部,服务器可以在HTTP响应中向用户服务器传送一个短流,以至于用户客户端可以在未来返回在一个cookie适用范围中的HTTP响应。比如说,服务器可以传送用户客户端带有值31d4d96e407aad42的会话标识符(SID)。这时,用户客户端在接下来的请求中返回会话标识符。

 

== Server -> User Agent ==

Set-Cookie: SID=31d4d96e407aad42

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42

 

服务器可以通过使用路径以及域性质改变cookie的缺省适用范围。比如说,服务器可以命令用户服务器返回example.com的每个路径以及域。

 

== Server -> User Agent ==

Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=example.com

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42

 

正如下一个例子中所展示的,服务器可以在用户客户端存储多重cookies。比如说,服务器可以通过返会两个Set-Cookie头部状态来存储会话标识符和用户偏好语言。留意到服务器使用安全以及HttpOnly属性为了更为敏感会话标识符提供额外的安全保护(详情参见4.1.2.部分)。

 

== Server -> User Agent ==

Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly

Set-Cookie: lang=en-US; Path=/; Domain=example.com

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42; lang=en-US

 

留意到上述的Cookie头部包含两个cookies,一个命名为SID,另一个为lang。如果服务器希望用户客户端在多重会话(用户客户端的重启)存留cookie,服务器可以在过期属性中指定过期时间。留意到如果用户客户端cookie保存超过了限额或者手动删除了服务器的cookie,用户客户端可能在过期时间之前删除cookie

 

== Server -> User Agent ==

Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42; lang=en-US

 

最后,移除cookie,服务器返回一个带有过去过期时间的Set-Cookie头部。服务器会成功地移除cookie当且仅当在Set-Cookie头部路径以及域属匹配当cookie初始创造的值。

 

== Server -> User Agent ==

Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42

 

4.服务器要求

这一部分描述行为良好的Cookie以及Set-Cookie 的语法以及语义的概况。

4.1Set-Cookie

 

Set-Cookie HTTP响应头部被用来从服务器传送cookies到用户客户端。

 

4.1.1.语法

 

通常情况上,Set-Cookie响应头部包含头部名称“Set-Cookie”为“:”所尾随的cookie。每一个cookiename-value-pair开始,为0及其以上个属性-值对。服务器“应该不”传送不能遵从以下语法的Set-cookie头部:

 

set-cookie-header  ="Set-Cookie:" SP set-cookie-string

set-cookie-string   =cookie-pair *( ";" SP cookie-av )

cookie-pair       = cookie-name"=" cookie-value

cookie-name      = token

cookie-value      = *cookie-octet / ( DQUOTE *cookie-octetDQUOTE )

cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E

; US-ASCIIcharacters excluding CTLs,

; whitespaceDQUOTE, comma, semicolon,

; and backslash

Token           = <token, defined in [RFC2616], Section2.2>

cookie-av        = expires-av / max-age-av / domain-av /path-av/ secure-av / httponly-av /

extension-av

expires-av        = "Expires=" sane-cookie-date

sane-cookie-date  = <rfc1123-date,defined in [RFC2616], Section 3.3.1>

max-age-av       ="Max-Age=" non-zero-digit *DIGIT

; In practice,both expires-av and max-age-av

; are limitedto dates representable by the

; user agent.

non-zero-digit     = %x31-39

; digits 1through 9

domain-av        = "Domain=" domain-value

domain-value     =<subdomain>

; defined in[RFC1034], Section 3.5, as

; enhanced by[RFC1123], Section 2.1

path-av           = "Path=" path-value

path-value        = <anyCHAR except CTLs or ";">

secure-av         = "Secure"

httponly-av       = "HttpOnly"

extension-av      = <any CHAR except CTLs or";">

 

留意到以上提到的一些语法名词参考文献和这份文档(使用[RFC 5234]中的ABNF)不同,使用了多样语法记法,

 

Cookie值的语义不是由这份文档定义的。

 

为了极大化用户客户端的兼容性,希望通过一个cookie值存储任意数据的服务器应该编码这份数据,比如说使用Base64[RFC4648]

 

cookie-av所产生的Set-cookie-string这部分被知晓为属性。为了极大化客户端的兼容性,服务器“应该不”生成同一种set-cookie-string中同种名称下的两种属性(详情请见第5.3部分中的用户客户端如何处理这种情形)。

 

服务器“应该不”包含在同一个cookie名称下的同一个响应的不止一个Set-Cookie头部状态(详情请见第5.3部分中的用户客户端如何处理这种情形)。

 

如果一个服务器向客户端同时发送包含Set-Cookie头部的多重响应(比如说当与多个套接口的用户客户端交流时)这些响应生成引起不可测行为的“race condition”。

注意:一些现存的用户客户端在两位数年份中不同。为了避免兼容性问题,服务器“应该”使用允许四位数年份的rfc1123数据格式。

 

注意:一些用户客户端在cookie中存储以及运行数据作为32字节的UNIX time_t值。在实现支持一些系统的time_t运行过程中安装漏洞可能会引发用户客户端在2038年后错误地运行数据。

 

4.1.2.语义(非规范)

 

本部分介绍Set-Cookie头部的简化语义部分。这些足够细化的语义对于 理解所有常见的服务器cookie用途。完整的语义在第5部分进行了解释。

 

当用户客户端收到Set-Cookie头部,用户客户端同时存储cookie以及相应的属性。与此同时,当用户客户端生成HTTP请求时,用户客户端在cookie头部拥有可行,非过期的cookie

 

除非cookie属性显现其他方面的情况,cookie返回给初始服务器(也许不返回初始服务器,比如说,返回给任何子域),在当前会话结束(为用户客户端所定义)后过期。用户客户端忽略不能被识别的cookie属性(而不是忽略整个cookie)。

 

4.1.2.1.过期属性

 

过期属性表明cookie最大存活时间,为cookie过期的日期以及时间所呈现。用户客户端不被允许去保留cookie直到经历特定的时间。事实上,用户客户端通常会出于存储压力或者隐私顾虑,移除cookie

 

4.1.2.2.最大缓存时间属性

 

最大缓存时间属性表明cookie的最大使用时限,为直到cookie过期的秒数所呈现。用户客户端不被允许去保留cookie直到特定的延续。事实上,用户客户端通常会出于存储压力或者隐私顾虑,移除cookie

 

注意:一些现存的用户客户端不能够支持最大缓存时间属性。不支持最大缓存时间属性的用户客户端会忽略这个属性。

 

如果一个cookie同时拥有过期属性以及最大缓存时间属性,最大缓存时间属性的控制权优先于cookie的过期时间。如果一个cookie不拥有过期属性以及最大缓存时间属性,用户客户端会保留这个cookie直到当前会话结束(为用户客户端所定义)。

 

4.1.2.3.域属性

 

域属性指定cookie会被发送的主机。比如说,如果域属性的值是“example.com”,用户客户端会在向example.comwww.example.com以及www.corp.example.com的发送HTTP请求的cookie头里面包含cookie(留意到即便是在字符不被允许的情况下,%x2E (".")会被忽略,但是后续的%x2E(".")会使得用户客户端忽略这个属性)。如果服务器忽略域性质,用户客户端仅会向初始服务器返回cookie

 

警告:一些现存的用户客户端在域属性被呈现的情况下,把缺省的域属性当做当前的主机名。比如说,如果example.com返回一个不包含域属性的Set-Cookie头部,这些用户客户端会错误地向www.example.com发送cookie

 

用户客户端会遗弃cookies,除非域属性指明的cookie适用范围包含初始服务器。比如说,用户客户端会接受来自foo.example.com的带有“example.com”或者“foo.example.com”的域属性的cookie,但是用户客户端不会接受来自foo.example.com的带有“bar.example.com”或者“baz.foo.example.com”的域属性的cookie

 

注意:出于安全的需要,许多用户客户端被配置去拒绝与公共后缀相符的域属性。比如说,一些用户客户端会拒绝“com”以及“co.uk”的域属性(详情请见第5.3节)。

 

4.1.2.4.路径属性

 

Cookie的适用范围为路径设置所限制。如果服务器忽略路径属性,用户客户端会将请求uri路径元素的名录当做缺省值(详情请见第5.1.4节)。

 

用户客户端会包含HTTP请求中cookie当且仅当请求uri的路径部分匹配cookie的路径属性(或者为cookie路径属性的分目录),在请求里%x2F("/")被当做目录的分隔符。

尽管在指定的主机上的不同路径分离cookies看起来有用,路径属性不能被作为安全的依赖。(详情见第8节)

 

4.1.2.5.安全属性

 

安全属性在安全(安全为用户客户端所定义)渠道上限制cookie的适用范围。当cookie拥有安全属性时,用户客户端会在HTTP请求中包含cookie当且仅当请求为安全通道(特别是指HTTP通过[RFC 2818]中的安全传输层协议(TLS))传输。

尽管保护cookies以免受到活跃的网络攻击者攻击,安全属性仅仅保护cookie的机密性。活跃的网络攻击者会从非安全的渠道重新书写安全cookie,扰乱完整性(详情请见第8.6节)。

 

4.1.2.6HttpOnly属性

 

HttpOnly属性限制cookieHTTP请求的适用范围。特别地,这属性指导用户客户端再通过“non-HTTPAPIs(比如说暴露cookie脚本的网络浏览器API)访问cookie时忽略cookie

 

留意到HttpOnly属性独立于安全属性:cookie可以同时拥有HttpOnly以及安全属性。

 

4.2Cookie

 

4.2.1.语法

 

用户客户端向初始服务器发送cookie头部的存储cookies。如果服务器符合4.1节的要求(且用户客户端符合第5节的要求),用户客户端会发送满足以下语法的cookie头部:

cookie-header = "Cookie:" OWS cookie-string OWS

cookie-string = cookie-pair *( ";" SP cookie-pair)

 

4.2.2.语义

 

每个cookie对呈现为用户客户端所存储的cookieCookie对包含用户客户端在Set-Cookie头部收到的cookie名称以及cookie值。

 

留意到cookie属性不会被返回。特别是,服务器不能仅仅通过cookie头部决定什么时候cookie会过期,有效cookie的主机,有效cookie的路径,或者cookie是否需要被设置带有安全或者HttpOnly属性。

 

Cookie头部的个体cookie的语义不能被这份文档所定义。服务器被期望去向cookie里面添加特有应用语义。

 

尽管cookies线性排列cookie头部,服务器“应该不”依赖序列顺序。特别地,如果cookie头部包含同一名称(比如说他们为不同路径或者域属性所设置)的两个cookie,服务器“应该不”依赖出现在头部的cookie的顺序。

 

5.客户端要求

本部分足够详细地规定了CookieSet-Cookie头部,使准确执行这些要求的客户端可以与现有的服务器交互(甚至也有那些不符合在第4节中描述的标准模式的标头)。

 

客户端可以强加比在此规定更多的限制(例如,为了提高安全性的);然而,实验已经表明,这样的严格性降低了客户端将能够与现有的服务器交互的可能性。

 

5.1.子组件算法

 

本节定义了客户端使用的一些算法,来处理CookieSet-Cookie头部的具体子部分。

 

5.1.1.日期

 

客户端必须使用等价于以下算法的一个算法来分析一个cookie日期。注意的是,定义为算法的一部分的各种布尔标志(例如,found-time, found-day-of-month, found-month, found-year)初始化为“未设置”。

 

  1. 使用下面的语法,划分cookie日期(cookie-date)到日期令牌(cookie-tokens)

     

    cookie-date     = *delimiterdate-token-list *delimiter

    date-token-list = date-token *( 1*delimiter date-token )

    date-token      =1*non-delimiter

     

    delimiter                   =%x09 / %x20-2F / %x3B-40 / %x5B-60 / %x7B-7E

    non-delimiter           =%x00-08 / %x0A-1F / DIGIT / ":" / ALPHA / %x7F-FF

    non-digit                   =%x00-2F / %x3A-FF

     

    day-of-month           =1*2DIGIT ( non-digit *OCTET )

    month              = ("jan" / "feb" / "mar" / "apr" /

    "may" / "jun" /"jul" / "aug" /

    "sep" / "oct" / "nov" /"dec" ) *OCTET

    year                            =2*4DIGIT ( non-digit *OCTET )

    time                  =hms-time ( non-digit *OCTET )

    hms-time         = time-field":" time-field ":" time-field

    time-field         = 1*2DIGIT

     

  2. 按照日期令牌出现在cookie日期的顺序,连续地处理每个日期令牌:

     

  1. 如果found-time标志未设置并且令牌和时间量相匹配,设置found-time标志,并分别设置hour-valueminute-valuesecond-value为在日期令牌中相应位数上表示的数字。跳过其余的子步骤,继续到下一个日期令牌。

     

  2. 如果found-day-of-month标志未设置并且日期令牌和day-of-month量相匹配,设置found-day-of-month标志,并设置day-of-month-value为在日期令牌中表示的数字。跳过其余的子步骤,继续到下一个日期令牌。

     

  3. 如果found-month标志未设置并且日期令牌和month量相匹配,设置found-month标志,并设置month-value为在日期令牌中表示的数字。跳过其余的子步骤,继续到下一个日期令牌。

     

  4. 如果found-year标志未设置并且日期令牌和year量相匹配,设置found-year标志,并设置year-value为在日期令牌中表示的数字。跳过其余的子步骤,继续到下一个日期令牌。

     

  1. 如果year-value大于或等于70且小于或等于99year-value1900

     

  2. 如果year-value大于或等于0且小于或等于69year-value2000

     

  1. 注:某些现有的客户端解释两位数字的年份不同。

     

  1. 终止这些步骤且不能解析cookie日期,如果:

     

    *       至少有一个标志found-timefound-day-of-monthfound-monthfound-year未设置,

     

    *       day-of-month-value小于1或大于31

     

    *       year-value小于1601

     

    *       hour-value大于23

     

    *       minute-value大于59,或

     

    *       second-value大于59.

     

    (请注意,闰秒不能在这个语法里表示)。

     

    6.让解析出的cookie日期就是day-of-monthmonthyearhourminutesecond (世界标准时间)分别是day-of-month-valuemonth-valueyear-valuehour-valueminute-valuesecond-value的日期。如果没有这样的日期存在,终止这些步骤且不能解析cookie日期。

     

    7.返回解析出的cookie日期,作为此算法的结果。

     

    5.1.2.规范化的主机名

     

    一个规范的主机名是由下面算法所产生的字符串:

     

  1. 把主机名转换为一个个人域名标签的序列。

     

    2.将每个不是非保留LDHNR-LDH)的标签转换为一个A-标签(A-label)(对于前者和后者见[RFC5890]2.3.2.1节),或转换为一个“punycode标签”(在[RFC3490]4节中一个由“ToASCII”转换得到的标签),转换要适当(见本规范第6.3节)。

     

    3.串联所得标签,由%x2E“.”)字符分开。

     

    5.1.3.域匹配

     

    一个字符串和给定的域字符串域匹配,如果以下至少一个条件成立:

     

    O   域字符串和字符串是相同的。(注意,在这一情况时域字符串和字符串都将被规范            化为小写)。

     

    O   以下所有条件都成立:

     

    *       域字符串是该字符串的后缀。

     

    *       该字符串的最后一个不包含在域字符串的字符是%x2E“.”)字符。

     

    *       该字符串是一个主机名(即不是一个IP地址)。

     

    5.1.4.路径和路径匹配

     

    客户端必须使用一个等价于以下算法的算法来计算一个cookie的默认路径:

     

    1.uri路径为请求uri的路径部分,如果这样的部分存在(否则为空)。例如,如果请求uri只包含一个路径(和可选的查询字符串),则uri路径就是该路径(没有%x3F“?”)字符和查询字符串),如果请求uri中包含一个完整的绝对uri,则uri路径是该uri的路径部分。

     

    2.如果uri路径是空的,或者uri路径的第一个字符不是%x2F“/”)字符,输出%x2F“/”),并跳过其余的步骤。

     

    3.如果uri路径包含不超过一个%x2F“/”)字符,输出%x2F“/”),并跳过其余的步骤。

     

    4.输出uri路径的字符,从第一个字符到最右侧的%x2F“/”),但不包括%x2F“/”)。

     

    一个请求路径和一个给定的cookie路径是路径匹配的,如果以下至少一个条件成立:

     

    O   cookie路径和请求路径是相同的。

     

    O   cookie路径是请求路径的前缀,并且cookie路径的最后一个字符是

     

    O   cookie路径是请求路径的前缀,并且请求路径的第一个不包含在cookie路径的字      符是一个%x2F“/”)字符。

     

    5.2.Set-Cookie头字段

     

    当一个客户端在一个HTTP响应中接收到一个Set-Cookie头部字段,客户端可以在它的实体中忽略Set-Cookie头部字段。例如,客户端可能希望阻止对“第三方”从设置cookie请求的响应(见7.1节)。

     

    如果客户端在它的实体中不忽略Set-Cookie头部字段,客户端必须把Set-Cookie头部字段的field-value作为set-cookie-string来分析(下面定义)。

     

    注意:下面的算法比第4.1节中的语法更宽容。例如,该算法去掉cookie的名称(name)和值(value)的首部和尾部的空格(但保留内部空格),而在第4.1节的语法禁止在这些位置上有空白。客户端使用这种算法,从而与不遵循第4节建议的服务器交互。

     

    客户端必须使用一个等价于以下算法的算法来分析一个“set-cookie-string”

     

  1. 如果set-cookie-string包含一个%x3B(“;”)字符:

     

    名称-值对(name-value-pair)字符串由直到第一个%x3B(“;”)但不包括(“;”)的字符组成,未分析的属性由剩余的set-cookie-string组成。

     

    否则:

     

    名称-值对(name-value-pair)字符串由set-cookie-string中包含的所有字符组成,未分析的属性是空字符串。

     

    2.如果名称-值对字符串缺少一个%x3D(“=”)字符,忽略整个set-cookie-string

     

  1. 名称字符串(可能为空)由直到第一个%x3D(“=”)字符但不包括(“=”)的字符组成,值字符串(可能为空)由第一个%x3D(“=”)字符后面的字符组成。

     

  2. 从名称字符串和值字符串移除首部和尾部的空格。

     

  3. 如果名称字符串为空,忽略整个set-cookie-string

     

  4. cookie-name就是名称字符串,cookie-value就是值字符串

     

    客户端必须使用一个等价于以下算法的算法来分析未分析的属性:

     

  1. 如果未分析的属性字符串为空,跳过其余的这些步骤。

     

  2. 丢弃未分析的属性的第一个字符(那是一个%x3B(“;”)字符)。

     

  3. 如果剩余的未分析的属性包含一个%x3B(“;”)字符:

     

    消耗未分析的属性的字符,直到第一个%x3B(“;”)字符,但不包括%x3B(“;”)

     

    否则:

     

    消耗其余的未分析的属性。

     

    cookie-av字符串就是在这步中所消耗的字符。

     

  4. 如果cookie-av字符串包含一个%x3D(“=”)字符:

     

    属性名字字符串(可能为空)由直到第一个%x3D(“=”)的字符组成,但不包含%x3D(“=”),属性值字符串(可能为空)由第一个%x3D(“=”)字符之后的字符组成。

     

    否则:

     

    属性名字字符串由整个cookie-av字符串组成,属性值字符串为空。

     

  5. 移除属性名字字符串和属性值字符串的首部和尾部的空格。

     

  6. 根据以下小节的要求处理属性名和属性值。(注意,无法识别属性名的属性将被忽略。)

     

  7. 返回到此算法的第一步。

     

    当客户端完成分析set-cookie-string时,客户端可以说从请求uri“收到一个cookie”,名称是cookie-name,值是cookie-value,属性为cookie-attribute-list。(收到一个cookie所引发的额外要求见5.3节。)

     

    5.2.1.过期(Expires)属性

     

    如果不区分大小写属性名和“Expires”字符串相匹配,客户端必须按如下方式处理cookie-av

     

    让过期时间(expiry-time)是分析属性值的结果,作为cookie日期(见第5.1.1节)。

     

    如果属性值不能被解析作为cookie日期,忽略cookie-av

     

    如果过期时间比客户端可以表示的最晚日期还晚,客户端也许会用最晚可表示的日期取代过期时间。

     

    如果过期时间比客户端可以表示的最早日期还早,客户端也许会用最早可表示的日期取代过期时间。

     

    cookie-attribute-list附加上属性名为Expires,属性值为expiry-time的属性。

     

    5.2.2.最大缓存时间(Max-Age)属性

     

    如果不区分大小写属性名和“Max-Age”字符串相匹配,客户端必须按如下方式处理cookie-av

     

    如果属性值的第一个字符不是一个数字或“-”字符,忽略cookie-av

     

    如果属性值的其余部分包含不是数字的字符,忽略cookie-av

     

    让Δ-秒作为属性值,转换为一个整数。

     

    如果Δ-秒小于或等于0,让过期时间(expiry-time)是最早的可表示的日期和时间。否则,让过期时间(expiry-time)是现在的日期和时间加上Δ-秒。

     

    cookie-attribute-list附加上属性名为Max-Age,属性值为expiry-time的属性。

     

    5.2.3.域(Domain)属性

     

    如果不区分大小写属性名和“Domain”字符串相匹配,客户端必须按如下方式处理cookie-av

     

    如果属性值为空,行为是不确定的。但是,客户端应该忽略整个cookie-av

     

    如果属性值字符串的第一个字符是%x2E(“.”)

     

    cookie域(cookie-domain)是不带首部%x2E(“.”)字符的属性值。

     

    否则:

     

    cookie域(cookie-domain)是整个的属性值。

     

    转换cookie域为小写。

     

    cookie-attribute-list附加上属性名为Domain,属性值为cookie-domain的属性。

     

    5.2.4.路径(Path)属性

     

    如果不区分大小写属性名和“Path”字符串相匹配,客户端必须按如下方式处理cookie-av

     

    如果属性值为空或者属性值的第一个字符不是%x2F(“/”)

     

    cookie路径(cookie-path)就是默认路径。

     

    否则:

     

    cookie路径就是属性值。

     

    cookie-attribute-list附加上属性名为Path,属性值为cookie-path的属性。

     

    5.2.5.安全(Secure)属性

     

    如果不区分大小写属性名和“Secure”字符串相匹配,客户端必须在cookie-attribute-list附加上属性名为Secure,属性值为空的属性。

     

    5.2.6.HttpOnly属性

     

    如果不区分大小写属性名和“HttpOnly”字符串相匹配,客户端必须在cookie-attribute-list附加上属性名为HttpOnly,属性值为空的属性。

     

    5.3.存储模型

     

    客户端存储每个cookie的以下字段:name(名称),value(值),expiry-time(过期时间),domain(域),path(路径),creation-time(创建时间),last-access-time(最后存储时间),persistent-flag(持久标志),host-only-flag(仅主机标志),secure-only-flag(仅安全标志),http-only-flag(仅http标志)。

     

    当客户端从请求uri“收到一个cookie”,名字是cookie-name,值是cookie-value,属性为cookie-attribute-list,客户端必须按下面方式处理cookie

     

  1. 客户端可能在它的实体中忽略一个收到的cookie。例如,客户端也许希望阻止来自“第三方”的应答,或者客户端不希望存储超过一定大小的cookie.

     

  2. 创建一个新的cookie,名称为cookie-name,值为cookie-value。设置创建时间和最后存储时间为当前的日期和时间。

     

  3. 如果cookie-attribute-list包含一个属性名为“Max-Age”的属性:

     

    设置cookiepersistent-flag为真。

     

    设置cookieexpiry-timecookie-attribute-list中最后一个属性名为“Max-Age”的属性的属性值。

     

    否则,如果cookie-attribute-list包含一个属性名为“Expires”的属性(不包含属性名为“Max-Age”的属性):

     

    设置cookiepersistent-flag为真。

     

    设置cookieexpiry-timecookie-attribute-list中最后一个属性名为“Expires”的属性的属性值。

     

    否则:

     

    设置cookiepersistent-flag为假。

     

    设置cookieexpiry-time为最新可表示的日期。

     

    4.如果cookie-attribute-list包含一个属性名为“Domain”的属性:

     

    让域属性为cookie-attribute-list中最后一个属性名为“Domain”的属性的属性值。

     

    否则:

     

    让域属性为空字符串。

     

  1. 如果客户端被配置为拒绝“公共后缀”并且域属性是公共后缀:

     

    如果域属性和规范化的请求主机相同:

     

    让域属性为空字符串。

     

    否则:

     

    忽略整个cookie并且终止这些步骤。

     

    注:“公共后缀”是由公共注册控制的域,如“com”,“co.uk”和“pvt.k12.wy.us”。这个步骤对于防止attacker.com通过设置一个cookie的域属性为“com”来破坏example.com的完整性是至关重要的。不幸的是,公共后缀(也称为“注册控制的域”)的集合随时间变化。如果可行的话,客户端应该使用一种跟上时间的公开后缀表,如Mozilla项目在<http://publicsuffix.org/>维持的。

     

  2. 如果域属性不为空:

     

    如果规范化的请求主机和域属性不是域匹配的:

     

    忽略整个cookie并且终止这些步骤。

     

    否则:

     

    设置cookiehost-only-flag为假。

     

    设置cookie的域(domain)为域属性(domain-attribute)。

     

    否则:

     

    设置cookiehost-only-flag为真。

     

    设置cookie的域(domain)为规范化的请求主机。

     

  3. 如果cookie-attribute-list包含一个属性名为“Path”的属性,设置cookie的路径是cookie-attribute-list中最后一个属性名为“Path”的属性的属性值。否则,设置cookie的路径为请求uri的默认路径。

     

  4. 如果cookie-attribute-list包含一个属性名为“Secure”的属性,设置cookiesecure-only-flag为真。否则,设置cookiesecure-only-flag为假。

     

  5. 如果cookie-attribute-list包含一个属性名为“HttpOnly”的属性,设置cookiehttp-only-flag为真。否则,设置cookiehttp-only-flag为假。

     

  6. 如果cookie是从一个“非HTTPAPI收到的,并且cookiehttp-only-flag已设置,终止这些步骤并且忽略整个cookie

     

  7. 如果cookie存储包含一个cookie与新创建的cookie有相同的名字、域和路径:

     

  1. 让旧的cookie成为现有的cookie,名字、域和路径与新创建的cookie相同。(注意,这个算法保持了不变性,即至多只有一个这样的cookie。)

     

    2.如果新创建的cookie是从一个“非HTTPAPI收到的,并且旧的cookiehttp-only-flag已设置,终止这些步骤并且忽略整个新创建的cookie

     

  1. 更新新创建的cookie的创建时间,来和旧的cookie的创建时间相匹配。

     

  2. cookie存储中移除旧的cookie

     

  1. 把新创建的cookie插入到cookie存储中。

     

    如果cookie有一个截止日期是过去的,cookie就是“过期的”。

     

    如果在cookie存储中有过期的cookie,在任何时间,客户端必须把cookie存储中所有过期的cookie驱逐。

     

    在任何时候,如果共享一个域领域的cookie数目超过了一些执行时定义的上限(如50cookie),客户端可以从cookie存储中“去除多余的cookie”。

     

    在任何时候,如果cookie数目超过了一些预定的上限(如3000cookie),客户端可以从cookie存储中“去除多余的cookie”。

     

    当客户端从cookie存储中去掉多余的cookie时,客户端必须按照以下的优先级顺序移除cookie

     

  1. 过期的cookie

     

  2. 共享一个域领域的cookie中,比其他cookie预定数目上限多的cookie

     

  3. 所有cookie

     

    如果两个cookie有相同的去除优先级,客户端必须先驱逐最早的最后访问日期的cookie

     

    当“当前会话结束”(由客户端定义),客户端必须从cookie存储中移除所有的cookie,并且把persistent-flag设置为假。

     

    5.4.Cookie头部

     

    客户端在Cookie HTTP请求头部中包含已存储的cookie

     

    当客户端产生了一个HTTP请求时,客户端禁止连接超过一个Cookie头部领域。

     

    客户端在它的实体中可能忽略Cookie头部。例如,在“第三方”从设置cookie的请求期间,客户端也许希望阻止发送cookie

     

    如果客户端把一个Cookie头部字段和HTTP请求连接,客户端必须发送cookie字符串(定义如下)作为头部字段的值。

     

    客户端必须使用一个等价于以下算法的算法来计算来自cookie存储和请求uri的“cookie字符串”:

     

  1. cookie列表就是在cookie存储中满足以下所有要求的cookie集合:

     

    *       要么:

     

    cookiehost-only-flag是真,并且规范化的请求主机和cookie的域相同。

     

    或者:

     

    cookiehost-only-flag是假,并且规范化的请求主机和cookie的域匹配。

     

    *       请求uri的路径和cookie的路径是路径匹配的。

     

    *       如果cookiesecure-only-flag是真,则请求uri的方案必须表示一个“安全”协议(有客户端定义)。

     

    注:“安全”协议的概念不由本文定义。通常情况下,如果协议利用传输层安全性,如SSLTLS,客户端会考虑协议安全。例如,大多数客户端认为“https”是一个可表示安全协议的方案。

     

    *       如果cookiehost-only-flag是真,则排除cookie字符串是为“非HTTPAPI而产生的cookie

     

  2. 客户端应该按如下顺序对cookie列表进行排序:

     

    *       长路径的cookie排在短路径的前面。

     

    *       路径长度相同的cookie,创建时间早的cookie排在创建时间晚的cookie的前面。

     

    注意:不是所有的客户端都按这个顺序对cookie列表排序,但是在写本文时这个顺序反映了普遍的做法,并且,在历史上,也有服务器采用这个顺序(错误地)。

     

  3. 更新cookie列表中每个cookie的最后存储时间为当前的日期和时间。

     

  4. 通过按顺序处理cookie列表中每一个cookie,将cookie列表连载为一个cookie字符串。

     

  1. 输出cookie名称,%x3D(“=”)字符,cookie值。

     

  2. 如果在cookie列表中有未处理的cookie,输出字符%x3B%x20(“; ”)

     

    注:不管它的名字,cookie字符串实际上是八位字节的序列,不是字符的序列。为了把cookie字符串(或者在其中的成分)转换成字符的序列(例如,为了呈现给用户),客户端也许希望尝试使用UTF-8字节编码[RFC3629]来表示八位字节。但是,这种表示可能失败,因为不是每一个八位字节的序列都是有效的UTF-8.

     

    实施注意事项

     

    6.1.限制

     

    实际的客户端的实现对可以存储的cookie有数量和大小的限制。一般使用的客户端应当提供下列每个最低功能:

     

    O   每个cookie至少4096个字节(由cookie的名字、值和属性长度的总和来测量)。

     

    O   每个域至少50cookie

     

    O   一共至少3000cookie

     

    服务器应该使用尽可能少和小的cookie,以避免到达了这些实施的限制,和减小网络宽度,由于Cookie头部被包含在每一个请求中。

     

    如果客户端无法返回在Cookie头部中一个或多个cookie,服务器应该适度降低限制,因为客户端可能随时从用户的顺序中驱逐任一cookie

     

    6.2.应用程序接口

     

    CookieSet-Cookie头部使用这样深奥的语法的一个原因就是许多平台(包括服务器和客户端)为cookie提供基于字符串的应用程序接口(API),这需要应用层程序设计人员来生成和解析CookieSet-Cookie头部所使用的语法,许多程序设计人员做的不正确,导致互通性的问题。

     

    通过提供更多的语义的APIcookie,平台可以被很好地服务,而不是提供基于字符串的API。推荐特定的API设计超出了本文的范围,但是有明显的好处去接受一个抽象的“日期”对象,而不是连续的日期字符串。

     

    6.3.IDNA依赖和迁移

     

    IDNA2008[RFC5890]取代了IDNA2003[RFC3490]。但是,两种规范之间有差异,因此在处理(例如,转换)注册在一个下和注册在另一个下的域名标签上会有差异。将会有一段时间的过渡期,在这期间基于IDNA2003的域名标签是存在于其他地方的。用户端应该实行IDNA2008[RFC5890],可以实行[UTS46][RFC5895],以方便其IDNA的过渡。如果客户端没实行IDNA2008,客户端必须实行IDNA2003[RFC3490].

     

    隐私注意事项

     

    Cookie因为让服务器跟踪用户而经常被批评。例如,当用户返回网站或访问另一个网站,一些“网络分析”公司使用cookies来识别。虽然cookie不是服务器可使用的唯一的机制通过HTTP请求来跟踪用户,cookie使跟踪容易,因为它们在客户端会话过程是持久的,并且可以在主机之间共享。

     

    7.1.第三方Cookies

     

    尤其令人担忧的是所谓的“第三方”cookie。在渲染HTML文档时,客户端经常从其他服务器(如广告网络)请求资源。这些第三方服务器可以使用cookie来跟踪用户,即使用户从未直接访问过这些服务器。例如,如果用户访问的网站包含来自第三方内容,后来访问另一个网站包含来自同一第三方的内容,第三方可以在这两个网站之间跟踪用户。

     

    一些客户端限制第三方cookie的行为。例如,一些客户端拒绝在第三方请求发送Cookie头部。其他用户拒绝处理Set-Cookie头部对第三方请求响应。客户端在他们的第三方cookie政策上变化很广泛。本文授予客户端很大的自由度来试验第三方cookie的政策,来平衡用户的隐私性和兼容性需求。但是,本文不认可任何特定的第三方cookie政策。

     

    第三方cookie拦截政策往往不能有效地实现他们隐私的目的,如果服务器尝试解决他们的限制来跟踪用户。特别地,通过往动态网址注入识别信息,两个协作的服务器往往可以根本无需使用cookie来跟踪用户。

     

    7.2.用户控件

     

    客户端应该为用户提供一种机制,管理存储在cookie存储中的cookie。例如,一个客户端可能允许用户删除在指定时间内接收到的所有cookie或所有与特定域名相关的cookie。此外,许多客户端包括用户界面元素,让用户检查存储在自己的cookie存储中的cookie

     

    客户端应该为用户提供一种机制,禁用cookie。当cookie被禁用,客户端不得在发出的HTTP请求包含Cookie头部,客户端不能对进来的HTTP响应处理Set-Cookie头部。

     

    一些客户端为用户提供防止会话过程cookie持久存储的选项。当这样设置,客户端必须当所有收到的cookiepersistent-flag被设置为false。一些流行的客户端通过“隐私浏览”模式[Aggarwal2010]表现此功能。

     

    一些客户端为用户提供批准个人写入到cookie存储的能力。在许多常见的使用场景,这些控件生成大量提示。但是,一些有隐私意识的用户发现这些控件仍然有用。

     

    7.3.到期时间

     

    虽然服务器可以为cookie设置到期时间为遥远的将来,大多数客户端实际上并不保留cookie几十年。服务器应当基于cookie的目的选择合理的cookie的到期时间,来促进用户的隐私,而不是无偿地选择长的到期时间。例如,一个典型的会话标识符可合理地设置在两周内到期。

     

    安全注意事项

     

    8.1.概述

     

    Cookie有许多安全缺陷。本节概述了几个比较突出的问题。

     

    特别地,cookie鼓励开发者依靠环境的权威认证,往往会变得容易受到攻击,如跨站请求伪造[CSRF]。此外,存储在cookie中的会话标识符时,开发者通常会创建会话固定漏洞。

     

    传输层加密,如HTTPS中采用的,不足以防止网络攻击者获得或改变受害者的cookie,因为cookie协议本身具有各种安全漏洞(见下文“弱保密”和“弱诚信”)。此外,在默认情况下,cookies不从网络攻击者提供机密性和完整性,与HTTPS结合使用时也是如此。

     

    8.2.外界权力

     

    使用cookie来验证用户身份的服务器要遭受安全漏洞问题,因为一些客户端让远程对方发出从客户端的HTTP请求(例如,通过HTTP重定向或HTML表单)。当发出这些请求,客户端附上cookie即使远程对方不知道cookie的内容,有可能让远程对方对不知情的服务器行使权力。

     

    虽然这个安全问题演进出许多名称(例如,跨站请求伪造,混淆代理人),来源于cookie的问题成为了外界权力的一种形式。Cookie鼓励服务器操作员把指定(以URL的形式)和授权(以cookie的形式)分开。因此,客户端可能提供给授权由攻击者指定的资源,可能导致服务器或它的客户做由攻击者指定的动作,就好像它们是由用户授权的。

     

    服务器操作员也许希望考虑通过将URL作为功能把指定和授权缠在一起,而不是为了授权而使用cookie。这种方式把秘密存储在URL中,需要远程实体提供自身的秘密,而不是在cookie中存储秘密。虽然这种方法也不是万能的,这些原则的正确应用会导致更强大的安全性。

     

    8.3.明文

     

    除非通过安全信道(例如,TLS)发送,在CookieSet-Cookie头部中的信息是在明文中被发送。

     

  1. 在这些头部传送的所有敏感信息被暴露给窃听者。

     

  2. 恶意中介可以改变头部,因为他们能往任一方向行驶,这会带来不可预知的结果。

     

  3. 恶意的客户端可能会在传输之前改变Cookie头部,带来不可预知的结果。

     

    当把cookie发送给客户端时(即使是通过安全通道发送cookie),服务器应该加密和标记cookie的内容(使用服务器期望的任何格式)。但是,加密和标记cookie内容并不能阻止攻击者把cookie从一个客户端移植到另一个,也不能阻止攻击者在以后重放cookie

     

    除了对每个cookie的内容加密和标记,需要更高的安全级别的服务器应该只有在通过安全信道时才使用CookieSet-Cookie头部。当通过安全信道使用cookie时,服务器应该为每个cookie设置安全属性(见第4.1.2.5节)。如果一个服务器没有设置安全属性,由安全通道提供的保护将在很大程度上无实际意义。

     

    例如,考虑一个网络邮件服务器,该服务器在cookie中存储会话标识符并且通常使用HTTPS。如果该服务器没有在它的cookie中设置安全属性,一个活跃的网络攻击者可以拦截客户端任何发出的HTTP请求,并通过HTTP重定向该请求到网络邮件服务器。即使网络邮件服务器没有监听HTTP连接,客户端仍然会在请求中包含cookie。活跃的网络攻击者可以拦截这些cookie,对服务器重放他们,并了解用户的电子邮件的内容。相反,如果该服务器已在它的cookie中设置安全属性,客户端将不会在明文请求中包含cookie

     

    8.4.会话标识符

     

    服务器通常在cookie中存储一个随机数(或“会话标识符”),而不是直接在cookie中存储会话信息(这可能会暴露给攻击者或被攻击者重放)。当服务器接收到一个带有随机数的HTTP请求时,服务器可以查找与使用该随机数作为密钥的cookie相关联的状态信息。

     

    如果攻击者了解到cookie的内容,使用会话标识符的cookie限制了攻击者可能会导致的破坏,因为随机数只有与服务器进行交互是有用的(不像非随机数的cookie的内容,可能本身是敏感的)。再者,使用单一的随机数可以防止攻击者把两个与服务器交互的cookie内容“拼接”在一起,这可能会导致服务器有不可预料的行为。

     

    使用会话标识符并非没有风险。例如,服务器应该注意避免“会话固定”的漏洞。会话固定攻击分为以下三个步骤。首先,攻击者把他或她的客户端的会话标识符移植到受害者的客户端。其次,受害者使用该会话标识符与服务器进行交互,可能把用户的凭据或机密信息灌输给会话标识符。第三,攻击者使用会话标识符直接与服务器进行交互,可能获得用户的授权或机密信息。

     

    8.5.弱保密性

     

    Cookie不会由端口提供隔离。如果一个cookie对在一个端口上运行的服务可读,该cookie对同一个服务器的另一个端口上运行的服务也可读。如果一个cookie对在一个端口上运行的服务可读,该cookie对同一个服务器的另一个端口上运行的服务也可读。出于这个原因,服务器不应同时对同一主机的不同端口上运行互不信任的服务,也不应该使用cookie存储安全敏感信息。

     

    Cookies不会由方案提供隔离。虽然与httphttps方案最常用,给定主机的cookie可能对其他方案也是可用的,如ftpgopher。尽管这种由方案导致的隔离的缺乏对允许访问cookie的非HTTPAPI(如HTMLdocument.cookie API)是最为明显的,实际上由方案导致的隔离的缺乏存在于处理cookie本身的需求(如,考虑通过HTTP检索一个有gopher方案的URI)。

     

    Cookie不会总是由路径提供隔离。虽然网络层协议不发送为一个路径存储的cookie到另一个路径,一些客户端通过非HTTP API暴露cookie,如HTMLdocument.cookie API。因为某些客户端(例如,网络浏览器)的不分离从不同路径接收的资源,从一个路径检索的资源可能能够访问为另一路径存储的cookie

     

    8.6.弱诚信性

     

    Cookie不会对兄弟域(及其子域)提供诚信保障。例如,考虑foo.example.combar.example.comfoo.example.com服务器可以设置一个cookie有“example.com”域属性(可能会覆盖由bar.example.com设置的已存在的“example.comcookie),客户端将在到bar.example.comHTTP请求中包含该cookie。在最坏的情况下,bar.example.com将无法区分该cookie和它自己设置的cookiefoo.example.com服务器可能能够利用这种能力来增加对bar.example.com的攻击。

     

    尽管Set-Cookie头部支持路径属性,路径属性不提供任何诚信保护,因为客户端将接受Set-Cookie头部的任意一个路径属性。例如,一个对http://example.com/foo/bar请求的HTTP响应可以设置cookie的路径属性为“/qux”。因此,服务器不应同时对同一主机的不同路径运行相互不信任的服务,也不应使用cookie来存储安全敏感信息。

     

    一个活跃的网络攻击者通过冒充来自http://example.com/的响应并且注入到Set-Cookie头部,也可以向发送到https://example.com/Cookie头部注入cookie。在example.comHTTPS服务器将无法区分这些cookie和它在HTTPS响应中自己设定的cookie。活跃的网络攻击者可能能够利用这种能力来增加对example.com的攻击,即使example.com使用HTTPS

     

    服务器可以通过加密和标记自己的cookie的内容部分缓解这些攻击。但是,使用密码不能缓解这一问题完全是因为攻击者可以把他或她从在用户的会话中的真实的example.com服务器收到的cookie重放,会带来不可预测的结果。

     

    最后,攻击者可能能够通过存储大量的cookie来迫使客户端删除cookie。一旦客户端达到其存储限制,客户端将被强制驱逐一些cookie。服务器不应该依赖于客户端保留cookie

     

    8.7.DNS依赖

     

    为了安全性cookie依靠域名系统(DNS)。如果DNS被部分或完全破坏,cookie协议可能不能提供应用所需的安全性能。

     

    IANA注意事项

     

    永久的消息头字段的注册表(参见[RFC3864])已经更新了以下注册。

     

    9.1.Cookie

     

    头字段名称:Cookie

     

    适用的协议:http

     

    状态:标准

     

    作者/变化控制者:IETF

     

    规范文档:本规范(第5.4节)

     

    9.2.Set-Cookie

     

    头字段名称:Set-Cookie

     

    适用的协议:http

     

    状态:标准

     

    作者/变化控制者:IETF

     

    规范文档:本规范(第5.2节)

     

    9.3.Cookie2

     

    头字段名称:Cookie2

     

    适用的协议:http

     

    状态:废弃的

     

    作者/变化控制者:IETF

     

    规范文档:[RFC2965]

     

    9.4.Set-Cookie2

     

    头字段名称:Set-Cookie2

     

    适用的协议:http

     

    状态:废弃的

     

    作者/变化控制者:IETF

     

    规范文档:[RFC2965]

     

    参考

     

    (略)

    10.1.引用标准

    (略)

    10.2.参考文献

    (略)

    附录A.致谢

    (略)

     

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值