如何为另一个域设置 cookie
Posted
技术标签:
【中文标题】如何为另一个域设置 cookie【英文标题】:How to set a cookie for another domain 【发布时间】:2011-10-09 08:07:04 【问题描述】:假设我有一个名为a.com
的网站,当加载该网站的特定页面时,比如页面链接,我想为另一个名为b.com
的网站设置cookie,然后将用户重定向到b.com
.
我的意思是,在加载a.com/link
时,我想为b.com
设置一个cookie,并将用户重定向到b.com
。
我测试了它,浏览器实际上收到了来自a.com/link
的cookie,但它没有在重定向请求中将那个cookie 发送到b.com
。正常吗?
我们可以为其他域设置 cookie 吗?
【问题讨论】:
请注意,如果您使用 URL 参数在 b.com 上设置 cookie,那么任何人都可以从任何网站强制 b.com 上的任何 cookie 值。 使用设置为 cookie 的 b.com 的 iFrame ;) 【参考方案1】:你不能,至少不能直接。这将是一个令人讨厌的安全风险。
虽然您可以指定 Domain attribute,但 the specification 表示“用户代理将拒绝 cookie,除非 Domain 属性指定包含源服务器的 cookie 的范围。”
由于源服务器是a.com
,不包括b.com
,所以不能设置。
您需要获取b.com
来设置cookie。您可以通过(例如)HTTP 重定向到 b.com
并返回。
【讨论】:
我知道这是一个旧响应,但为什么会有安全风险?您可以在控制台或扩展中设置 cookie?如果您可以为不同的域设置 cookie,为什么会很重要? @Timberman — 问题是关于在网站上运行的 javascript,not 在开发人员工具中,not 在显式安装的扩展程序中。这将是一个安全风险,因为任何访问evil-hack.com
的人都可以为their-favourite-website.com
设置一个cookie,这会改变他们在该网站上的偏好。
我明白,但它是如何存在安全风险的?我很确定它与安全无关?
@Timberman — 如果您看不到攻击者的网站改变您对完全不同网站的偏好的问题,那么我不知道如何更清楚地解释它。
我看到了问题,但我不明白它是如何构成安全风险的。我同意你的观点,javascript 不应该能够为不同的域设置 cookie,但是如果它能够设置 cookie,那么它是一个安全问题吗?【参考方案2】:
您不能为其他域设置 cookie。允许这样做会带来巨大的安全漏洞。
您需要获取 b.com 才能设置 cookie。如果 a.com 将用户重定向到b.com/setcookie.php?c=value
setcookie 脚本可以包含以下内容来设置 cookie 并重定向到 b.com 上的正确页面
<?php
setcookie('a', $_GET['c']);
header("Location: b.com/landingpage.php");
?>
【讨论】:
但是a.com在重定向到b.com的时候可以以header的形式插入同样的数据,不是吗?为什么这不存在安全漏洞? @Coder,setcookie 函数将导致 cookie 标头从 b.com 发送到浏览器。 a.com 无法从 b.com 发送 cookie 标头。 是的,这是非常不安全的,但它确实有效。如果 OP 拥有 a.com 和 b.com 并且 cookie 非常简单,那么也许没问题。 最好在答案中注意到这是不安全的,尽管它有效。 你怎么能这么说但是 youtube 正在读取 gmail 创建的 cookie 以便在 youtube 上显示他们的帐户?【参考方案3】:无法为其他域设置 cookie。
如果您想将数据传递到另一个域,您可以将其编码到 url。
a.com -> b.com/redirect?info=some+info (and set cookie) -> b.com/other+page
【讨论】:
从 url 设置会话 cookie 存在安全风险。 url 通常会被记录下来,并允许攻击者窃取用户会话【参考方案4】:您可能可以为此使用Iframe
。 Facebook 可能使用了这种技术。您可以在此here 上阅读更多信息。 *** 使用类似的技术,但使用 html5 本地存储,更多关于这方面的信息,请参阅他们的 blog
【讨论】:
iframe 非常适合我的解决方案,只需像普通 get 请求一样在 url 中包含值并使用 cookie 值从服务器响应 请注意,您必须正确配置 Access-Control-Allow-Origin 才能正常工作。【参考方案5】:与上面的答案类似,但您可以在域 A 上设置图像,而不是重定向到页面并再次返回,这会导致糟糕的用户体验。
<img src="http://www.example.com/cookie.php?val=123" style="display:none;">
然后在 cookie.php 中的 example.com 域 B 上,您将拥有以下代码:
<?php
setcookie('a', $_GET['val']);
?>
致Subin
【讨论】:
不错的技巧... :) 当心这可能是一个非常糟糕的主意。通过基本上让任何人发送精心制作的 GET 请求以将该 cookie 设置为他们想要的任何值,您正在规避非常有意的 cookie 保护。我不知道你对那个 cookie 做了什么,但我希望它不涉及银行余额。 我可以向您保证,这不涉及银行余额。但好点:) 如果在这种情况下每个人都可以使用自己的参数调用此域,您可以通过添加另一个参数来增加安全性。使用数据和额外的盐创建一个哈希,并将其作为参数传递。在您的 cookie.php 中,只需通过重新创建令牌并比较它们来验证 $_GET['val'] 中的数据。 如果您以这种方式发送 GET,您也可以使用 AJAX。【参考方案6】:如果您有a.my-company.com
和b.my-company.com
而不仅仅是a.com
和b.com
,您可以为.my-company.com
域发出cookie - 它将被接受并发送到这两个域。
【讨论】:
是否可以在 a.my-company.com 中为 b.my-company.com 创建一个 cookie? 除非 my-company.com 在Public Suffix Black-hole List 中,在这种情况下,浏览器会默默地忽略所有设置 cookie 的尝试! :'-( 你绝对是对的。但如果事情发生了。然后我们必须找到解决方案。这不是这个问题的解决方案。不给建议只是解决方案【参考方案7】:见RFC6265:
除非域属性,否则用户代理将拒绝 cookie 指定包含源的 cookie 的范围 服务器。例如,用户代理将接受一个带有 “example.com”或“foo.example.com”的域属性来自 foo.example.com,但用户代理不会接受带有 “bar.example.com”或“baz.foo.example.com”的域属性。
注意:出于安全原因,许多用户代理被配置为拒绝 对应于“公共后缀”的域属性。例如, 一些用户代理会拒绝“com”或“co.uk”的域属性。 (有关详细信息,请参阅第 5.3 节。)
但上述使用 image/iframe 的解决方法有效,但由于不安全,不推荐使用。
【讨论】:
【参考方案8】:您不能,但是...如果您拥有这两个页面,那么...
1)您可以通过查询参数(http://siteB.com/?key=value)发送数据
2) 您可以在站点 A 内创建站点 B 的 iframe,并且可以将帖子消息从一个地方发送到另一个地方。由于站点 B 是站点 B cookie 的所有者,因此它可以通过处理正确的发布消息来设置您需要的任何值。 (您应该阻止其他不受欢迎的发件人向您发送消息!这取决于您和您决定用来防止这种情况发生的机制)
【讨论】:
【参考方案9】:在此链接中,我们将找到解决方案Link。
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "b.com", 1);
【讨论】:
那行不通。请参阅the specification:“用户代理将拒绝 cookie,除非 Domain 属性为 cookie 指定了包含源服务器的范围。”【参考方案10】:从 A 发送 POST 请求。POST 请求仅在服务器端,客户端无法访问。
您可以使用 CURL(推荐,服务器端)或隐藏的 method="POST"
表单(客户端)从 a.com
向 b.com
发送 POST 请求。如果您选择后者,您可能希望混淆您的 JavaScript,以便用户无法理解算法并对其进行干预。
在b.com
上做一个网关来设置cookies:
<?php
if (isset($_POST['data'])
setcookie('a', $_POST['data']);
header("Location: b.com/landingpage");
?>
如果您想进一步提高安全性,请在双方(a.com
和 b.com
)上实现一个函数,以使用加密密码加密(a.com
)和解密(b.com
)数据。
如果您正在尝试做一些必须绝对安全的事情(例如转移登录会话),请尝试 oAuth 或从 https://api.cloudianos.com/docs#v2/auth 获得一些灵感
【讨论】:
【参考方案11】:这是我用过的。请注意,此 cookie 以开放 (http) 方式传递,因此不安全。我不会将它用于任何需要安全的事情。
-
站点 A 生成一个令牌并作为 URL 参数传递给站点 B。
站点 B 获取令牌并将其设置为会话 cookie。
您可能可以添加加密/签名以确保安全。研究如何正确地做到这一点。
【讨论】:
是的,我正在考虑这样做,但据说在 url 中传递令牌是不安全的,因为它们绕过 ssl 并且它们存储在日志和浏览器历史记录中。 正如我所评论的,这可以确保安全。如果站点 A 和站点 B 共享一个加密密钥,则第三方无法读取它。您需要做的不仅仅是加密。您可能需要包含一个随机数来防止各种 MITM 攻击。这可能是安全的,但你需要做更多的功课。毕竟,https 是建立在 http 之上的。 有道理。因此,您首先进行一些 ajax 握手,然后公开传递现在安全的 url。 如果 A -> B 调用是 https,那么网络调用是安全的,因为 URL 是加密的。您可以通过加密进一步保护数据。 A 和 B 需要共享一个加密密钥。 A 加密 URL 令牌。它在浏览器中被加密记录,这意味着没有人可以读取它,因为解密密钥在服务器上,而不是浏览器上。理想情况下,您会将加密信息作为 http 标头传递,这样它就不会被记录或记录在历史记录中。阅读生成 oauth 令牌,了解如何进一步保护(数字签名和散列以检测篡改)、nonce 以防止 MITM 等。 他也是我最喜欢的电影角色。很高兴你遵守!以上是关于如何为另一个域设置 cookie的主要内容,如果未能解决你的问题,请参考以下文章