HTTPOnly Cookie 是通过 XmlHTTPRequest 提交的 withCredentials=True 吗?

信息安全 javascript csrf
2021-08-13 22:23:07

我在这里有一个两部分的问题。

我有一个访问特权 REST 端点的 javascript webapp。我想防止 CSRF。

目前,我构建了一个登录系统,它返回一个包含加密有效负载(加密然后 MAC)的登录 cookie。我有理由确信 cookie 的内容不会在我不知情的情况下被篡改或伪造。

我知道使用所说的 cookie 来保护我的端点容易受到 CSRF 的攻击,因为 cookie 是由浏览器随任何请求自动提交的。我还认为不鼓励使用双重提交 Cookie 模式,因为它需要将 cookie HTTPOnly 值设置为 False,这会增加某些攻击的风险。

我想做的是将 auth cookie(用于在中期保持登录)设置为 HTTPOnly 和 Secure。然后,我希望 javascript 客户端向令牌端点发出 XHR GET 请求,在该端点可以验证 cookie,并且可以直接发回短期令牌(其中包含指向我存储在数据库中的信息的句柄)到客户端,没有用户代理重定向。然后,javascript 客户端将使用短期令牌来授权对我的 REST 端点的调用。

我的第一个问题是,这个流程有什么明显的缺陷吗?这似乎是对 REST 同步器令牌模式的合理改编,但我想知道是否存在严重缺陷,或者该过程是否有其他最佳实践。

我已经考虑实施 OAuth 2.0 隐式授予流程,但我希望存在 auth cookie,以便我可以在适当的时间内保持登录。

第二个问题是:如果我设置 withCredentials=True,浏览器会使用我的 XHR 将 HTTPOnly cookie 提交到令牌端点吗?我知道 HTTPOnly 限制了 javascript 读取 cookie 的能力,但是 cookie 标记是否会在请求中对客户端不可见?

我已经搜索了谷歌的答案,而我的 google-fu 让我失望了。我能找到的只有大量关于阅读 HTTPOnly cookie 但不提交它们的文章。

提前感谢您的任何帮助或建议!

2个回答

是的,它们已提交。请参阅W3C 规范

HTTPOnly 旨在缓解 XSS 之类的攻击,但如果攻击者在您的站点中有 XSS,则他们不需要 CSRF。您是否考虑过加密令牌模式

我也认为不鼓励使用 Double Submit Cookie 模式,因为它需要将 cookie HTTPOnly 值设置为 False

它不需要设置HTTPOnly为 false。仅当您有一些 JavaScript 代码将隐藏表单字段值设置为与 cookie 相同时。只需将 cookie 值输出到页面服务器端(当然要正确编码以避免 XSS),就可以在没有 JavaScript 的情况下做到这一点。

我的第一个问题是,这个流程有什么明显的缺陷吗?

这似乎很好,因为由于同源策略,攻击者无法读取 GET 请求。但是,如果您的信息高度安全,那么防范JSON 劫持可能是个好主意。这在很长一段时间内都不是问题(想想 Firefox 3),但如果任何缺陷被重新引入任何浏览器,您可以采取基本步骤以低成本保护您的网站。例如,将其更改为 POST 并在响应中添加无法解析的内容。这在某种程度上违背了 REST 原则,但这是您必须自己权衡的事情。

第二个问题是:如果我设置 withCredentials=True,浏览器会使用我的 XHR 将 HTTPOnly cookie 提交到令牌端点吗?

是的,它会的。HTTPOnly 保护客户端上的 JavaScript 本身,它不会影响 HTTP 请求。