HTTP cookie 端口是特定的吗?

Posted

技术标签:

【中文标题】HTTP cookie 端口是特定的吗?【英文标题】:Are HTTP cookies port specific? 【发布时间】:2010-12-09 09:21:51 【问题描述】:

我在一台机器上运行了两个 HTTP 服务。我只想知道他们是否共享他们的 cookie,或者浏览器是否区分两个服务器套接字。

【问题讨论】:

【参考方案1】:

当前的 cookie 规范是 RFC 6265,它取代了 RFC 2109 和 RFC 2965(这两个 RFC 现在都被标记为“历史”),并正式确定了 cookie 实际使用的语法。它明确指出:

    简介

...

由于历史原因,cookie 包含许多安全和隐私方面的缺陷。例如,服务器可以指示给定的 cookie 用于“安全”连接,但 Secure 属性在存在活动网络攻击者的情况下不提供完整性。 同样,给定主机的 cookie 在该主机上的所有端口之间共享,即使网络浏览器使用的通常“同源策略”会隔离通过不同端口检索的内容。

还有:

8.5。保密性差

Cookie 不提供端口隔离。如果运行在一个端口上的服务可以读取 cookie,则运行在同一服务器的另一个端口上的服务也可以读取 cookie。如果 cookie 可由一个端口上的服务写入,则该 cookie 也可由运行在同一服务器的另一个端口上的服务写入。因此,服务器不应在同一主机的不同端口上运行相互不信任的服务并使用 cookie 来存储安全敏感信息。

【讨论】:

/etc/hosts 可用于为127.0.0.1 创建比localhost 更多的cookie 域【参考方案2】:

根据RFC2965 3.3.1(浏览器可能会也可能不会),除非通过Set-Cookie 标头的port 参数明确指定端口,cookie 可能会或可能不会发送到任何端口。

Google 的 Browser Security Handbook 说:默认情况下,cookie 范围仅限于当前主机名上的所有 URL - 并且不绑定到端口或协议信息。 以及稍后的一些行 无法将 cookie 限制为仅单个 DNS 名称 [...] 同样,无法将它们限制为特定端口。(另外,请记住,IE 不会将端口号纳入其同源策略完全。)

因此,在这里依赖任何明确定义的行为似乎并不安全。

【讨论】:

RFC 6265,它取代了 RFC 2965,消除了 Set-Cookie 标头中的 Port 参数(因为在实践中几乎没有人实际使用它),并且非常明确地表明同一 cookie主机不再可以通过端口区分。 如果域中有端口,IE 9 甚至不会在后续请求中将 cookie 发回 是否有任何浏览器仍在考虑其 cookie 的 SOP 中的端口? 如果域中有端口,Chrome 甚至不会设置 cookie。【参考方案3】:

这是一个非常老的问题,但我想我会添加一个我使用的解决方法。

我的笔记本电脑上运行了两个服务(一个在端口 3000 上,另一个在 4000 端口上)。 当我在(http://localhost:3000http://localhost:4000)之间跳转时,Chrome 会传入同一个 cookie,每个服务都不会理解 cookie 并生成一个新的。

我发现,如果我访问 http://localhost:3000http://127.0.0.1:4000,问题就消失了,因为 Chrome 为 localhost 和 127.0.0.1 保留了一个 cookie。

同样,此时可能没有人关心,但它对我的情况很容易且有帮助。

【讨论】:

是的,因为 cookie 与主机/域名相关联,所以 localhost 上的 cookie 不能与 127.0.0.1 共享,反之亦然。但是,无论端口如何,同一主机/域上的 cookie 都是可共享的。 当然有。我(可能还有数百万其他开发人员)一直使用 localhost 进行测试。除非添加的端口有所不同:localhost:8080 另外,你可以使用 127.0.0.1, 127.0.0.2, 127.0.0.3 等等……它们都是 localhost 的意思。 如果您愿意编辑您的主机文件(Unix 上的 /etc/hosts),您可以为 localhost 设置任意数量的有意义的名称。 @DavidBalažic 不,“localhost”表示 127.0.0.1。 127.0.0.2 通常没有名字。这些地址是不同的单播地址,被 TCP 协议视为任何不同的单播地址,但它们都是本地的。【参考方案4】:

这是 cookie SOP(Same Origin Policy)中的一个很大的灰色区域。

理论上,您可以在域中指定端口号,cookie 不会被共享。实际上,这不适用于多个浏览器,您会遇到其他问题。因此,这仅在您的网站不面向公众且您可以控制要使用的浏览器时才可行。

更好的方法是为同一个 IP 获取 2 个域名,而不是依赖于 cookie 的端口号。

【讨论】:

不再是灰色地带。 RFC 6265 是当前的 cookie 标准,通过简单地消除使用不同端口在同一主机上分离 cookie 的能力,消除了任何混淆。【参考方案5】:

解决此问题的另一种方法是使会话 cookie 的名称与端口相关。例如:

mysession8080 用于在端口 8080 上运行的服务器 mysession8000 用于在端口 8000 上运行的服务器

您的代码可以访问网络服务器配置以找出您的服务器使用的端口,并相应地命名 cookie。

请记住,您的应用程序将同时接收两个 cookie,并且您需要请求与您的端口对应的一个。

cookie 名称中不需要有确切的端口号,但这样更方便。

一般来说,cookie 名称可以对特定于您使用的服务器实例的任何其他参数进行编码,因此可以通过正确的上下文对其进行解码。

【讨论】:

这适用于在不同端口号上共享主机名的相互信任的 Web 服务。但所有与主机相关的 cookie 都将发送到该主机的所有 Web 服务,无论其名称如何。如果主机允许恶意的非特权运营商在不同的端口号上运行 Web 服务,则运营商可以滥用原始 Web 服务客户的浏览器,将所有与主机相关的 cookie(包括秘密 cookie)发送到共享主机的恶意 Web 服务。 【参考方案6】:

在 IE 8 中,cookie(仅针对 localhost 进行验证)在端口之间共享。在 FF 10 中,它们不是。

我已经发布了这个答案,以便读者至少有一个具体的选项来测试每个场景。

【讨论】:

【参考方案7】:

我在同一台机器上运行(并尝试调试)两个不同的 Django 应用程序时遇到了类似的问题。

我使用这些命令运行它们:

./manage.py runserver 8000
./manage.py runserver 8001

当我在第一个登录然后在第二个登录时,我总是退出第一个,反之亦然。

我在我的 /etc/hosts

上添加了这个
127.0.0.1    app1
127.0.0.1    app2

然后我用这些命令启动了这两个应用程序:

./manage.py runserver app1:8000
./manage.py runserver app2:8001

问题解决了:)

【讨论】:

您可以使用127.0.0.1:8000 一秒钟,localhost:8000 一秒钟,也许::1:8000(也许是[::1]:8080)三秒钟,而无需接触主机文件。跨度> 可以写成一行:::1 app1 app2 app3 app4 app5 appN【参考方案8】:

这是可选的。

可以指定端口,因此 cookie 可以是特定于端口的。没必要,Web 服务器/应用程序必须关心这个。

来源:German Wikipedia article,RFC2109,第 4.3.1 章

【讨论】:

Sounds like it's more complicated than this in real life.

以上是关于HTTP cookie 端口是特定的吗?的主要内容,如果未能解决你的问题,请参考以下文章

session和cookie的知识总结

端口为零的绑定会将您绑定到空闲端口。这是便携的吗? [关闭]

问题1: js 不能往非80端口写cookie? 问题2: 如果访问题地址是IP地址,80端口,是不是能写cookie

跟踪特定的 IP 和端口

如何更改Apache中的HTTP监听端口

CORS跨域操作cookie