ChatGPT解决这个技术问题 Extra ChatGPT

HTTP cookie 端口是特定的吗?

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


C
Community

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

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

并且:

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


/etc/hosts 可用于为 127.0.0.1 创建比 localhost 更多的 cookie 域
I
Ilan Frumer

根据 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。
P
Pat

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

我的笔记本电脑上运行了两项服务(一个在端口 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 协议视为任何不同的单播地址,但它们都是本地的。
Z
ZZ Coder

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

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

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


它不再是一个灰色地带。 RFC 6265 是当前的 cookie 标准,通过简单地消除使用不同端口在同一主机上分离 cookie 的能力,消除了任何混淆。
M
Manolis M. Tsangaris

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

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

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

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

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

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

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


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

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

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


A
Andrea Grandi

我在同一台机器上运行(并尝试调试)两个不同的 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
M
Matthew Murdoch

这是可选的。

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

来源:German Wikipedia articleRFC2109,第 4.3.1 章