【问题标题】:CORS Security: Set Access-Control-Allow-Origin to Origin on Request HeaderCORS 安全性:在请求标头上将 Access-Control-Allow-Origin 设置为 Origin
【发布时间】:2014-10-15 06:26:44
【问题描述】:

我不确定 Access-Control-Allow-Origin 和 cookie 等方面的安全细节。

我试图生成一个允许从任何网站进行身份验证的 API。因此我需要设置:

Access-Control-Allow-Origin*

Access-Control-Allow-Credentialstrue

由于安全限制,这是不允许的。

但是,将Access-Control-Allow-Origin 响应标头设置为请求的Origin 标头的值会有什么问题?这是一个巨大的安全漏洞吗?!

例如(节点)

// CORS
app.all('*', function (req, res, next) {
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Headers', 'origin, content-type, accept');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if (req.method == 'OPTIONS') {
        res.status(200).end();
    }

    next();
});

【问题讨论】:

  • 这是一个安全限制,而不是组织级别的策略
  • 它与可能的重复非常相似,但我想知道不进行配置查找并通过 ping 请求源来允许任何源的安全隐患
  • 是的,现在我明白了——the CORS spec 不允许 Access-Control-Allow-Origin:*Access-Control-Allow-Credentials:true[allow-origin] 字符串“*”不能用于支持凭据。
  • 我认为您会在security.stackexchange.com 得到更快/更好的响应。如果您对迁移感兴趣,请标记您自己的问题并使用自定义标记说明您的帖子作者并且您希望迁移该问题。我认为您的问题在这里完全是主题,但我个人怀疑它可能在 Security.SE 上做得更好。
  • 好主意,这是解决问题的一种可能方法,我们不能一次允许多个页面,只是 *.例如,如果您还想在 localhost 上允许开发页面,则不能使用静态标头设置来实现。

标签: node.js security cors


【解决方案1】:

如果您接受 API 的“默认”会话管理方法,则 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 标头组合可能会给您的网站带来风险。例如,如果会话是通过 cookie(常见)、基本/NTLM/Kerberos 身份验证(发生)或客户端证书(非常少见)维护的。

如果您使用 Authentication: Bearer 标头或类似标头,其中浏览器不会自动发送会话令牌,那么这可能不会成为问题(除非您也接受其他方法,并且您的合法用户使用这些方法) .

将 Access-Control-Allow-Origin 响应标头设置为请求的 Origin 标头的值会有什么问题?

这与允许来源* 完全相同,并且不需要任何攻击者的额外努力。但是,您将能够以类似的方式解决此问题。如果您有一个预先批准的要允许访问的域列表,您可以从发送的Origin 标头中检查该域,如果它与允许的域匹配,您可以在Access-Control-Allow-Origin 中反映Origin

* 的安全风险在于它会允许任何网站读取可能包含私人用户数据的内容。

当您允许任何域使用凭据(实际上是 Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: true)联系您的 API 时,您也允许其他域可能劫持数据。

例如,当您的受害者登录到您的 API 时,攻击者会伪造一封电子邮件给您的受害者,让您在攻击者的域 www.evil.com 上观看有趣的视频。在播放猫视频时,攻击者域向您的 API 发出 AJAX 请求 www.example.com/Get_User_Profile_Details 并读取用户的详细信息,包括出生日期、家庭地址、电话号码和其他详细信息。隐含的 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true 将允许 CORS 在正常情况下被 Same Origin Policy 阻止时检索此数据。

因此,为了防止这种情况,您应该只为已批准的域输出 Access-Control-Allow-Credentials 标头。

我试图生成一个允许从任何网站进行身份验证的 API。

如果您确实需要从任何网站访问,那么您需要小心。您可以根据会话 ID 存储初始身份验证请求的 Origin(即用户输入其用户名和密码)。对于每个请求,您都需要检查 Origin 并查看它是否与存储在服务器端会话中的 Origin 匹配。如果是,则输出 Access-Control-Allow-Origin: https://www.example.org 标头(假设 www.example.org 是用户登录的位置),如果不是,则根本不输出 Access-Control-Allow-Origin

您还可以找到this post interesting

【讨论】:

  • 我理解这现在暴露的问题。谢谢!顺便说一句,当我说“来自任何网站的身份验证”时,我的意思是任何 我的 网站。所以一个起源白名单是可以的;我只是想知道问题的细节。干杯!
【解决方案2】:

我不是这些方面的专家......

我原则上建议它不仅仅是使用“*”,因为调用者需要一些努力才能输入他们想要的任何内容。

我建议如果你真的想把事情捆绑起来(对已批准的 [API?] 用户),那就是在配置中保留原点并每次检查?

正如我所说,我不是专家。

为了记录,Greg 在工作时坐在我对面.. 我本可以和他聊聊我的观点,但我想要 SO 点 :-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2019-02-07
    • 2018-09-19
    • 2019-06-19
    • 2021-12-19
    • 2016-08-03
    • 2021-08-12
    相关资源
    最近更新 更多