访问控制允许来源:* 带有不记名令牌

信息安全 jwt 科尔斯
2021-08-28 19:15:46

在测试单页应用程序时,我发现 REST 端点返回允许跨域访问的 CORS 标头:

access-control-allow-credentials: true
access-control-allow-methods: GET, POST, DELETE, PUT
access-control-allow-origin: *

这些端点处理机密数据,所以我对此的最初反应是提出一个高风险漏洞。

然而,当我试图利用这个问题时,我发现我做不到。该站点在授权标头中使用不记名令牌而不是会话 cookie。虽然可以进行跨域请求,但无法附加所需的标头。

这种模式有什么风险?这是一种明智的做事方式吗?

2个回答

有几件事意味着不太可能被利用。

开始

access-control-allow-credentials: true
access-control-allow-origin: *

无效组合

重要提示:在响应凭据请求时,服务器必须指定域,并且不能使用通配符。如果标头通配符为:Access-Control-Allow-Origin: *,上述示例将失败。由于 Access-Control-Allow-Origin 明确提及http://foo.example,因此将凭证识别内容返回给调用 Web 内容。

另一件事是授权标头不是简单的标头,因此需要进行预检以导致Access-Control-Allow-Headers响应返回该标头。服务器不返回它也会阻止任何 CSRF 攻击,因为预飞行会阻止它。

除非它允许标头,否则通常不可能添加自定义标头跨域,除非您尝试使用过去在某些浏览器上工作的 Flash 漏洞利用。

这种模式有什么风险?这是一种明智的做事方式吗?

由于指定此标头组合是无效的,因此这确实不是一种明智的做事方式。那里可能有一些奇怪的浏览器允许它,并且该网站很容易受到攻击(如果任何潜在的受害者正在使用它)。允许所有来源但不允许有凭证的请求允许受害者浏览器被用作一种代理,以访问其他无法访问的资源。但是,由于无法附加承载标头(没有 Flash 漏洞利用)并被允许通过Access-Control-Allow-Headers,我不会说这是高风险的。此外,由于攻击者没有受害者的不记名令牌,因此将发出的任何跨域请求都将在攻击者的会话下,而不是在受害者的会话下。

我可能会指出它是一个建议性项目,他们应该检查他们的 CORS 标头是否符合他们的意图。

IMO 不记名令牌 + 宽松的 CORS 将两个糟糕的决定组合成一个可能是灾难性的决定。

不记名令牌方法通过 (1) 网络通信大大增加令牌暴露,因此依赖于正确设置 TLS,以及 (2) 在需要保护和仔细处理令牌的用户代理(浏览器、移动设备)端。

不幸的是,CORS 的宽松设置进一步加剧了他们的客户端安全问题。由于允许用户代理连接到任何其他域以下载 JS 库,因此他们最好确保这些其他站点不仅值得信赖,而且具有出色的安全性,因此它们不会被轻易破坏。您不希望驻留在用户代理中的令牌被从其他站点下载的一些恶意脚本窃取 - 这是结合这两种选择时引入的风险。

减少代币盗窃的建议:

  • 如果不记名令牌是绝对必要的,限制 CORS 以防止跨域访问。
  • 另一方面,如果需要跨域,则使用授权代码授予,其中令牌完全驻留在服务器端并且永远不会暴露给用户代理。