为什么要在 API 的 HTTP 响应中包含 CSP 标头?

Why should we include CSP headers in the HTTP response for an API?

提问人:Renan 提问时间:8/23/2021 更新时间:8/30/2021 访问量:2571

问:

OWASP 建议在 API 响应中使用,以避免拖放式点击劫持攻击。Content-Security-Policy: frame-ancestors 'none'

但是,CSP 规范似乎表明,加载 HTML 页面后,同一上下文中的任何其他 CSP 规则都将被丢弃,而不受任何影响。这在我对CSP如何工作的心理模型中是有道理的,但如果OWASP推荐它,那么我肯定会错过一些东西。

谁能解释一下,在HTML页面已经加载并且已经评估了“主要”CSP之后,XHR请求中的CSP标头如何提高安全性?这在浏览器中是如何工作的?

HTTP 安全 http-headers content-security-policy 客户端攻击

评论


答:

0赞 kenlukas 8/24/2021 #1

该指令将在页面加载时向浏览器指示它不应在框架(包括 frame、iframe、embed、object 和 applet 标记)中呈现。换言之,该政策不允许它被任何其他页面框定。frame-ancestors 'none'

加载时读取 API 或页面的 CSP 标头。这不是事后发生的事情。“主”CSP 不相关,因为它是帧中的 URI 将 CSP 发送给自身。浏览器只是接受该 URI 的请求frame-ancestor 'none'

frame-ancestors 指令限制可以使用 frame、iframe、object 或 embed 嵌入资源的 URL。资源可以使用此指令来避免许多 UI 修正 [UISECURITY] 攻击,方法是避免嵌入到潜在敌对上下文中的风险。

参考资料
CSP 帧祖先 点击劫持防御备忘单
内容安全策略
Web 安全指令 帧祖先

评论

0赞 Renan 8/26/2021
“加载时读取 API 或页面的 CSP 标头。”您指的是在 iFrame 上下文中加载 API 请求吗?如果没有,你能再详细说明一下,因为我可能没有理解它。
5赞 granty 8/25/2021 #2

在已加载 HTML 页面并已评估“主要”CSP 之后,XHR 请求中的 CSP 标头如何提高安全性?

你是对的,浏览器从主页使用 CSP,只需忽略与 XHR 请求一起发送的 CSP 标头。

但你没有考虑第二种情况 - API 响应在浏览器的地址栏或框架中打开。在这种情况下,Cookie 将可用于响应页面,如果在 API 中检测到 XSS(例如,在 PyPI 简单端点 API 中),则攻击者可能会获得用户的机密数据。
因此,最好使用“default-src 'none'”策略以及 404/403/500 等页面来保护 API 响应。

评论

0赞 Renan 8/26/2021
这是有道理的。我总是想到 XHR 上下文中的 API 调用,而忘记了对 API 的“直接”或“顶级”请求的可能性,这些请求可能会返回 text/html。
4赞 knight87 8/30/2021 #3

谁能解释一下,在HTML页面已经加载并且已经评估了“主要”CSP之后,XHR请求中的CSP标头如何提高安全性?这在浏览器中是如何工作的?

除了上面的正确答案之外,帧通常用于 CSP 旁路。 如果页面中允许某个框架(未被 CSP 阻止),则该框架具有自己的 CSP 范围。因此,如果为数据创建一些 API,则不希望将其设置为帧,因为它可用于绕过原始 CSP(例如数据外泄)。

所以你可以通过设置 来阻止这个漏洞,然后你的 API 将拒绝被框架。Content-Security-Policy: frame-ancestors 'none';

有关详细信息,请参阅这篇关于绕过 CSP 的文章。POC 使用了一个创造性的技巧:

frame=document.createElement(“iframe”);
frame.src=”/%2e%2e%2f”;
document.body.appendChild(frame);

这反过来又会触发未设置任何 CSP 的 NGINX 错误代码页。许多生产 CSP 容易受到此问题的影响。

由于不在框架页面上设置 CSP 基本上默认为没有 CSP(一切都是打开的),因此本文建议:

CSP 标头应存在于所有页面上,事件位于 Web 服务器返回的错误页面上