无法访问在iframe中加载的自己域上的httponly标记的cookie

Unable to access httponly flagged cookie on own domain loaded in iframe

本文关键字:httponly cookie 自己 访问 iframe 加载      更新时间:2023-09-26

我正在制作一个chrome扩展在网页上注入一个iframe 并显示一些东西

内容加载在iframe是从https://example.com和我有完全控制在它。我试图通过document.cookie从iframe(我认为应该可用)访问https://example.com的cookie。这不是让我访问httponly标记的cookie,我不知道原因。毕竟这不是跨域的。是吗?

下面是我用来获取cookie

的代码
jQuery("#performAction").click(function(e) {
    e.preventDefault();
    console.log(document.domain); // https://example.com
    var cookies = document.cookie;
    console.log('cookies', cookies);
    var httpFlaggedCookie1 = getCookie("login_sess");
    var httpFlaggedCookie2 = getCookie("login_pass");
    console.log('httpFlaggedCookie1 ', httpFlaggedCookie1 ); // shows blank
    console.log('httpFlaggedCookie2 ', httpFlaggedCookie2 ); // shows blank
    if(httpFlaggedCookie2 != "" && httpFlaggedCookie2 != ""){
        doSomething();
    } else{
        somethingElse();
    }
});

对此有什么建议吗?

Chrome默认禁止使用JavaScript读写HttpOnly cookie。

然而,因为你正在写一个chrome扩展,你可以使用chrome.cookies.getchrome.cookies.set读/写,与manifest.json声明的cookies权限。并且要知道chrome.cookies只能在后台页面访问,所以也许你需要做一些事情与消息传递

好了。在第三方cookie被弃用后,我努力使httponly cookie显示在iframe中。最终我解决了这个问题:

这是我想到的:

  1. 安装一个service worker,它的脚本由你的应用服务器渲染(比如PHP)。在这里,您可以在闭包中输出cookie,这样其他脚本甚至注入的函数都无法读取它们。尝试从其他用户代理加载相同的URL将不会获得cookie,因此它是安全的。

  2. 是的,service worker是定期卸载的,但是每次它再次加载时,它会有最新的cookie,因为#1。

  3. 在服务器端代码响应渲染中,每次添加Set-Cookie报头时,也要添加具有相同内容的Set-Cookie- js报头。让Service Worker拦截这个响应,读取这个cookie,并在闭包中更新私有对象。

  4. 在"fetch"事件中,添加一个特殊的请求头,如cookie - js,并传递应该在cookie中传递的内容。在向服务器发送请求之前,将此添加到请求头中。通过这种方式,您可以将所有"httponly"cookie发送回服务器,而Javascript无法看到它们,即使实际的cookie被阻止!

  5. 在你的服务器上,处理Cookie-JS报头并将其合并到你通常的cookie机制中,然后继续像往常一样运行你的代码。

虽然这对我来说似乎很安全- 如果有人报告安全漏洞,我会很感激!! -有一个比cookie更好的机制。

考虑使用不可提取的私钥,比如ECDSA来签署有效负载的哈希值,同样使用service worker。(在像视频这样的超大负载中,你可能希望你的哈希只采样一部分负载。)让客户端在建立新会话时生成密钥对,并在每个请求时发送公钥。在服务器上,将公钥存储在会话中。您还应该有一个以(publicKey, cookieName)为主键的数据库表。然后,您可以根据用户的公钥查找所有cookie——这是安全的,因为密钥是不可提取的

此方案实际上比cookie更安全,因为cookie是承载令牌,有时会受到会话固定攻击或中间人攻击(即使使用https)。请求有效负载可以在服务器上伪造,最终用户无法证明他们没有发出该请求。但是使用第二种方法,用户的service worker将在客户端签署所有内容。

最后要注意的是:Web的工作方式,您仍然必须信任托管您所在站点域的服务器。它可以很容易地将JS代码交付给您,以便使用您生成的私钥签署任何内容。但是它不能窃取私钥本身,所以它只能在你加载页面时签名。因此,从技术上讲,如果您的浏览器设置为缓存顶级页面"100年",并且该页面在其加载的每个资源上都包含子资源完整性,那么您可以确保代码不会更改。我希望浏览器能在这种情况下显示某种绿色挂锁。如果网站的审计员可以指定这样一个顶级页面的哈希值,那么浏览器的绿色挂锁将链接到在该哈希值下发布的安全评论(例如,在IPFS上,或者在同样具有哈希值的Web URL上),那就更好了。简而言之,通过这种方式,网站最终可以发布你可以信任的代码,这些代码对于每个URL(例如应用程序的版本)都是不可变的,而其他人可以发布对这些代码的安全审计和其他评估。

也许我应该做一个浏览器扩展来做到这一点!