浏览器 cookie 域如何工作?

Posted

技术标签:

【中文标题】浏览器 cookie 域如何工作?【英文标题】:How do browser cookie domains work? 【发布时间】:2010-11-06 23:18:39 【问题描述】:

由于我遇到了奇怪的域/子域 cookie 问题,我想知道浏览器如何处理 cookie。如果他们以不同的方式做到这一点,那么了解它们的差异也很不错。

换句话说 - 当浏览器接收到一个 cookie 时,该 cookie 可能有一个域和一个附加到它的路径。或者不是,在这种情况下,浏览器可能会用一些默认值代替它们。问题1:它们是什么?

稍后,当浏览器即将发出请求时,它会检查其 cookie 并过滤掉它应该为该请求发送的那些。它通过将它们与请求路径和域进行匹配来做到这一点。问题2:匹配规则是什么?


添加:

我之所以问这个问题是因为我对某些极端情况感兴趣。喜欢:

.example.com 的 cookie 是否可用于 www.example.com.example.com 的 cookie 是否可用于 example.comexample.com 的 cookie 是否可用于 www.example.comexample.com 的 cookie 是否可用于 anotherexample.comwww.example.com 能否为example.com 设置 cookie? www.example.com 能否为www2.example.com 设置 cookie? www.example.com 能否为.com 设置 cookie? 等

添加 2:

另外,有人可以建议我应该如何设置 cookie 以便:

可以通过www.example.comexample.com设置; www.example.comexample.com 都可以访问它。

【问题讨论】:

【参考方案1】:

虽然现在有RFC 2965(Set-Cookie2,已经过时的RFC 2109)应该定义cookie,但大多数浏览器并不完全支持它,而只是遵守@ 987654323@.

Domain属性值和有效域是有区别的:前者取自Set-Cookie头域,后者是该属性值的解释。根据 RFC 2965,以下内容应适用:

如果Set-Cookie头域没有Domain属性,则有效域为请求的域。李> 如果存在 Domain 属性,则其值将用作有效域(如果该值不以 . 开头,它将由客户端添加)。

拥有有效域还必须domain-match设置当前请求的域;否则 cookie 将被修改。相同的规则适用于选择要在请求中发送的 cookie。


将这些知识映射到您的问题上,以下内容应该适用:

Domain=.example.com 的 Cookie 可用于 www.example.com Domain=.example.com 的 Cookie 可用于 example.com 带有Domain=example.com 的Cookie 将被转换为.example.com,因此也可用于www.example.com Domain=example.com 的 Cookie可用于 anotherexample.com www.example.com 能够为 example.com 设置 cookie www.example.com能够为 www2.example.com 设置 cookie www.example.com能够为 .com 设置 cookie

要为/by www.example.comexample.com 设置和读取 cookie,请分别为 .www.example.com.example.com 设置它。但第一个 (.www.example.com) 只能被该域下的其他域访问(例如 foo.www.example.combar.www.example.com)其中.example.com 也可以被 example.com 下的任何其他域访问(例如 foo.example.combar.example.com )。

【讨论】:

@Gumbo 所以 a.b.c.example.com 可以访问域 c.example.com 的 cookie? 非常对此问题的后续跟进问题。我自己的经验和这个:webmasters.stackexchange.com/questions/55790/… 表明 example.com 的域对 www.example.com 不可用,但这个例子表明并非如此。这个例子是错误的,还是我(很可能)误解了。很抱歉线程死灵,但想确保这个出色的答案对于像我这样的未来困惑的新手来说是 100% 准确的 :) 这个答案有点过时了;请参阅下面的my answer。 为什么不将 example.com 设置为可用于 www.example.com? (因为它是 example.com 的“www”子? Set-Cookie2 本身已过时。继续使用 Set-Cookie。【参考方案2】:

以前的答案有点过时了。

RFC 6265 于 2011 年发布,基于当时的浏览器共识。 从那时起,公共后缀域出现了一些复杂情况。我写了一篇解释当前情况的文章 - http://bayou.io/draft/cookie.domain.html

总而言之,关于 cookie 域应遵循的规则:

cookie 的源域是发起请求的域。

如果源域是IP,则不能设置cookie的域属性。

如果没有设置 cookie 的 domain 属性,则 cookie 仅适用于其源域。

如果设置了 cookie 的域属性,

cookie 适用于该域及其所有子域; cookie 的域必须与源域相同或父域 cookie 的域不得是 TLD、公共后缀或公共后缀的父级。

可以得出一个cookie总是适用于它的源域。

cookie 域不应有前导点,如 .foo.com - 只需使用 foo.com

举个例子,

x.y.z.com 可以为自己或父母设置 cookie 域 - x.y.z.comy.z.comz.com。但不是com,这是一个公共后缀。 domain=y.z.com 的 cookie 适用于 y.z.comx.y.z.coma.x.y.z.com 等。

公共后缀示例 - comeduukco.ukblogspot.comcompute.amazonaws.com

【讨论】:

@roelleor - 恰恰相反。编写 rfc6265 是为了总结在实践中实际处理 cookie 的方式:) 是的,rfc 非常准确地反映了主要浏览器的行为方式。我最近对浏览器的测试证实了这一点。不过,在涉及公共后缀的特殊情况下,它们可能会有所不同。 前导点的后果是什么? @UpTheCreek - 根据 rfc6265,客户应忽略前导点 x.y.z.com可以给z.com设置一个cookie是不是很奇怪? 那么如果xyzcom可以给yzcom设置cookie,并且域yzcom的cookie适用于wyzcom...那是否意味着xyzcom可以给wyz设置cookie com?【参考方案3】:

要获得广泛的报道,请查看RFC2965 的内容。当然,这并不一定意味着所有浏览器的行为方式都完全相同。

然而,一般来说,如果 cookie 中没有指定默认路径,则默认路径的规则是 Set-Cookie 标头到达的 URL 中的路径。同样,Domain 的默认值是 Set-Cookie 到达的 URL 中的完整主机名。

域的匹配规则要求 cookie 域与发出请求的主机相匹配。 cookie 可以通过包含 * 来指定更广泛的域匹配。在 Set-Cookie 的域属性中(浏览器可能会有所不同的这一区域)。匹配路径(假设域匹配)很简单,请求的路径必须在 cookie 上指定的路径内。通常会话 cookie 使用 path=/ 或 path=/applicationName/ 设置,因此 cookie 可用于应用程序的所有请求。


__对添加的回应:__ .example.com 的 cookie 是否可用于www.example.com? 是的 .example.com 的 cookie 是否可用于 example.com? 不知道 example.com 的 cookie 是否可用于www.example.com? 不应该…… * example.com 的 cookie 是否可用于 anotherexample.com? 没有 www.example.com 能否为 example.com 设置 cookie? 是的 www.example.com 能否为 www2.example.com 设置 cookie? (通过 .example.com 除外) www.example.com 可以为 .com 设置 cookie 吗? (不能在命名空间中设置这么高的 cookie,也不能为 .co.uk 之类的东西设置一个)

* 我现在无法对此进行测试,但我知道至少 IE7/6 会将路径 example.com 视为 .example.com

【讨论】:

我在我的问题中添加了一些有趣的边缘案例。你能推荐一下吗?【参考方案4】:

此问题的最后一个(确切地说是第三个)RFC 是 RFC-6265(过时的 RFC-2965,反过来又过时了 RFC-2109)。

According to it 如果服务器省略域属性,用户代理将只返回 cookie 到 源服务器(给定资源所在的服务器)。但是也警告,一些现有的用户代理将缺少的域属性视为存在域属性并包含当前主机名(例如,如果 example.com 返回没有域属性的 Set-Cookie 标头,这些用户代理也会错误地将 cookie 发送到 www.example.com。

当Domain属性被指定时,它会被视为完整的域名(如果属性中有前导点将被忽略)。服务器应该匹配属性中指定的域(具有完全相同的域名或作为它的子域)以获取此 cookie。更准确地说是specified here。

所以,例如:

cookie 属性Domain=.example.com 等价于Domain=example.com 具有此类域属性的 cookie 将 example.comwww.example.com可用 对于 another-example.com,具有此类域属性的 cookie不可用 指定像 Domain=www.example.com 这样的 cookie 属性将关闭 www4.example.com

PS:Domain 属性中的尾随逗号会导致用户代理忽略该属性 =(

【讨论】:

【参考方案5】:

我在 2019 年最新的 Chrome、Firefox、Safari 中测试了所有案例。

对已添加的回复:

.example.com 的 cookie 是否可用于 www.example.com? 是的 .example.com 的 cookie 是否可用于 example.com? 是的 example.com 的 cookie 是否可用于 www.example.com? NO,没有通配符的域只匹配自身。 example.com 的 cookie 是否可用于 anotherexample.com? 没有 www.example.com 能否为 example.com 设置 cookie? ,它将能够为 '.example.com' 设置 cookie,但不能为 'example.com' 设置 cookie。 www.example.com 能否为 www2.example.com 设置 cookie? 。但它可以为 .example.com 设置 cookie,www2.example.com 可以访问。 www.example.com 能否为 .com 设置 cookie? 没有

【讨论】:

cookie 域中的前导域是用词不当。您的回答与 Mozilla 关于 Cookie 的文档直接矛盾:developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie 请参阅域部分:Contrary to earlier specifications, leading dots in domain names (.example.com) are ignored.【参考方案6】:

众所周知,RFC 不能反映现实。

最好检查draft-ietf-httpstate-cookie,正在进行中。

【讨论】:

【参考方案7】:

有一些规则可以确定浏览器是否会接受 Set-header 响应标头(服务器端 cookie 写入),使用 javascript 设置的 cookie 的规则/解释略有不同(我尚未测试 VBScript)。

然后有一些规则可以确定浏览器是否会随页面请求一起发送 cookie。

主要浏览器引擎如何处理域匹配以及如何解释路径值中的参数存在差异。你可以在文章How Different Browsers Handle Cookies Differently

中找到一些经验证据

【讨论】:

【参考方案8】:

www.example.com 能否为.com 设置 cookie?

不可以,但example.com.fr 可以为example2.com.fr 设置一个cookie。 Firefox 通过维护一个 TLD 列表来防止这种情况发生:http://securitylabs.websense.com/content/Blogs/3108.aspx

显然 Internet Explorer 不允许两个字母的域设置 cookie,我想这可以解释为什么 o2.ie 只是重定向到 o2online.ie。我经常想知道。

【讨论】:

“com.fr”被称为“公共后缀”。 cookie 域不能是公共后缀。见 rfc 6265 和 publicsuffix.org 是的,有一个解决方案,但它是一个非常混乱的解决方案。这种标签应该嵌入到 DNS 中,而不是单独进行。 是的,也许您指的是“dbound”。但这可能会产生更多问题;比如,对 http 客户端实现提出了挑战。 如果这些信息以某种方式从浏览器暴露给 javascript,将会很有用。否则,不可能以编程方式确定您是否可以在某个级别的域上设置 cookie。毕竟,您不能在每次通话时都检查该列表!【参考方案9】:

读到第 3.3.2 节关于拒绝 cookie 的内容让我很惊讶:

https://www.rfc-editor.org/rfc/rfc2965

这表示浏览器应该拒绝来自 x.y.z.com 且域为 .z.com 的 cookie,因为“x.y”包含一个点。因此,除非我误解了 RFC 和/或上述问题,否则可能会添加一些问题:

.example.com 的 cookie 是否可用于www.yyy.example.com?没有。

由源服务器www.yyy.example.com 设置的 cookie 是否具有域 .example.com 的值是否由用户代理发送到 xxx.example.com?没有。

【讨论】:

rfc 已过时。基于浏览器共识的新 rfc 6265 允许将带有 z.com 的 cookie 应用于 z.com所有 子域。

以上是关于浏览器 cookie 域如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

SpringMvc CORS跨域设置

如何从 WebBrowser Control 中为任意域设置和删除 cookie

如何跨域传递 cookie

C# asp.net 如何跨域获取cookie

CSRF攻击简介

浏览器不为显式域保存 cookie