HTTP cookie端口特定吗?


355

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

Answers:


329

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

  1. 介绍

...

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

并且:

8.5。机密性差

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


129

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

Google的《浏览器安全手册》说:默认情况下,Cookie范围仅限于当前主机名上的所有URL,而不受端口或协议信息的约束。以及以后的几行内容同样,无法将Cookie限制为单个DNS名称,也没有办法将Cookie限制为特定端口。(此外,请记住,IE根本不将端口号纳入其同源策略。)

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


75
代替RFC 2965的RFC 6265消除了标头中的Port参数Set-Cookie(因为实际上几乎没有人实际使用它),并且非常明确地表明端口不再可以区分同一主机上的cookie。
Remy Lebeau

5
如果域中有端口,则IE 9甚至不会在后续请求中发送回cookie
axk

3
是否有任何浏览器仍在考虑在其Cookie的SOP中使用端口?
贝尔图兹

5
如果其中包含域的端口,Chrome甚至不会设置Cookie。
Pim Heijden

76

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

我的笔记本电脑上运行着两项服务(一项在端口3000上,另一项在4000上)。当我在(http://localhost:3000http://localhost:4000)之间跳转时,Chrome浏览器将传递相同的cookie,每个服务将无法理解该cookie并生成一个新的cookie。

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

再说一次,没有人会在乎这一点,但这对我的情况很简单而且很有帮助。


1
是的,因为cookie与主机名/域名相关联,所以localhost不能与cookie 共享,127.0.0.1反之亦然。但是同一主机/域上的cookie(无论端口如何)都是可以共享的。
Remy Lebeau

3
当然可以。我(可能还有数百万其他开发人员)一直使用localhost进行测试。除非添加的端口有所不同:localhost:8080
DavidBalažic2014年

53
另外,您可以使用127.0.0.1、127.0.0.2、127.0.0.3等...它们都表示本地主机。
DavidBalažic2014年

3
我不能对此表示赞同,因为它不能回答问题,但这是一个很好的提示,谢谢!
Martin T.

2
如果您愿意编辑主机文件(在Unix上为/ etc / hosts),则可以使用尽可能多的有意义的名称作为localhost。
西拉斯·布朗

20

这是Cookie SOP(相同来源政策)中的灰色大区域。

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

更好的方法是使用相同的IP获得2个域名,而不依赖于端口号来存储Cookie。


9
它不再是灰色区域。RFC 6265是当前的cookie标准,它通过简单地消除使用不同端口在同一主机上分离cookie的能力,消除了对此的任何困惑。
Remy Lebeau

18

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

  • mysession8080(在端口8080上运行的服务器)
  • 在端口8000上运行的服务器的mysession8000

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

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

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

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


9

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

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


4

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

问题解决了 :)


4
您可能可以使用127.0.0.1:8000一个,localhost:8000第二个,甚至可以::1:8000(也许[::1]:8080)使用三分之一,而无需触摸hosts文件。
特拉维斯·沃森

1
您可以将其放在一行中:::1 app1 app2 app3 app4 app5 appN
aeroson

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.