如果请求源与模式匹配,是否存在允许所有CORS来源的安全漏洞?

时间:2015-04-08 23:18:25

标签: security cors

我们要求允许跨源请求,前提是原产地属于公司域名。虽然这个问题不是C#或Web API特定的,但下面的代码片段展示了我们的策略。

我们有一组定义允许来源的正则表达式:

    private static readonly Regex[] AllowedOriginPatterns = new[]
    {
        new Regex(@"https?://\w[\w\-\.]*\.company.com",
                  RegexOptions.Compiled | RegexOptions.IgnoreCase)
    };

稍后,在我们的ICorsPolicyProvider属性中,我们测试原点。如果原点与任何模式匹配,我们将原点添加到允许的原点集:

    var requestOrigin = request.GetCorsRequestContext().Origin;
    if (!string.IsNullOrWhiteSpace(requestOrigin) &&
        AllowedOriginPatterns.Any(pattern => pattern.IsMatch(requestOrigin)))
    {
        policy.Origins.Add(requestOrigin);
    }

这种方法的好处是,我们可以支持大量灵活的授权来源,并限制未经授权的来源,所有这些都不会在我们的标题中放置数百个来源。

我们的反向代理部分有HTTP头重写问题。在某些情况下,反向代理会将Access-Control-Allow-Origin值替换为主机。对我来说似乎很可疑,但这不是我的问题。

建议我们更改我们的代码,以便如果原点符合我们的先决条件,我们返回*而不是回应响应中的原点。

我的问题是,我们是否通过将Access-Control-Allow-Origin: *返回到符合我们前提条件的来源来打开潜在的安全漏洞。我希望浏览器检查每个请求的访问控制标头。如果是这样,我并不过分担心。如果没有,我可以想象一个运行不受信任的网站的攻击者利用以前收到*的可信来源的浏览器。

我已阅读OWASP article on scrutinizing CORS headers。这篇文章没有反映我的任何担忧,这是令人放心的;但是,在向前推进之前,我想询问社区。

更新

事实证明,这个问题无效。在探索此实现之后,我们发现允许所有来源的凭证请求是不允许的。在对我们失败的实现进行故障排除后,我找到了两个很清楚的小语句。

来自W3C Recommendation,第6.1节:

  

注意:字符串“*”不能用于支持凭据的资源。

来自Mozilla Developer Network

  

重要说明:在响应凭证请求时,服务器必须指定域,并且不能使用通配符。

这证明我们的实施最终令人失望;但是,我认为充分保护有证书的CORS请求的复杂性可以解释为什么这是一个禁止的场景。

我感谢所有的帮助和考虑。

1 个答案:

答案 0 :(得分:1)

  

我的问题是我们是否通过将Access-Control-Allow-Origin:*返回到符合我们前提条件的起源来打开潜在的安全漏洞。

潜在地,如果浏览器(或代理服务器)缓存响应。但是,if you are not specifying Access-Control-Allow-Credentials then the risk is minimal

要降低发送*的风险,请确保设置相应的HTTP响应标头以防止缓存:

Cache-Control: private, no-cache, no-store, max-age=0, no-transform
Pragma: no-cache
Expires: 0

请注意,指定private是不够的,因为攻击者可能会定位已访问过您网页并将其存储在浏览器缓存中的人。

作为替代方案,您可以使用Vary: Origin标头。但是,如果某些客户未发送Origin标题,您可以end up with * cached for all requests

最好的方法是修复反向代理问题,以便您的页面根据您的代码返回相应的Origin。但是,如果这不可行,则只有在使用积极的反缓存策略时*才可以。此外,如果*Access-Control-Allow-Credentials或缺失,则所有请求的false可能没问题 - 这取决于您的应用是否保持基于敏感用户的状态。