为什么我们应该在 API 的 HTTP 响应中包含 CSP headers?

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

OWASP recommends 在 API 响应中使用 Content-Security-Policy: frame-ancestors 'none' 以避免 drag-and-drop 式点击劫持攻击。

但是,CSP 规范 在 HTML 页面加载后,相同上下文中的任何其他 CSP 规则将被丢弃而没有效果。这在我对 CSP 如何工作的心智模型中是有意义的,但如果 OWASP 推荐它,那么我肯定会遗漏一些东西。

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

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

API 或页面的 CSP header 在加载时读取。这不是事后发生的事情。 “主要”CSP 不相关,因为它是帧中的 URI,它正在为自己发送 CSP。浏览器仅通过该 URI

接受 frame-ancestor 'none' 请求

The frame-ancestors directive restricts the URLs which can embed the resource using frame, iframe, object, or embed. Resources can use this directive to avoid many UI Redressing [UISECURITY] attacks, by avoiding the risk of being embedded into potentially hostile contexts.

参考资料
CSP frame-ancestors
Clickjacking Defense Cheat Sheet
Content Security Policy
Web Sec Directive Frame Ancestors

how can a CSP header in a XHR request improve security, after the fact that the HTML page is already loaded and the "main" CSP already evaluated?

你是对的,浏览器使用主页中的 CSP 并忽略随 XHR 请求一起发送的 CSP header。

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

Can anyone explain how can a CSP header in a XHR request improve security, after the fact that the HTML page is already loaded and the "main" CSP already evaluated? How that works in the browser?

添加到 ,框架通常用于 CSP 旁路。 如果页面允许框架(未被 CSP 阻止),框架有它自己的 CSP 范围。因此,如果您为数据创建一些 API - 您不想将其设置为框架,因为它可用于绕过原始 CSP(例如数据泄露)。

所以你可以通过设置Content-Security-Policy: frame-ancestors 'none';来屏蔽这个漏洞,然后你的API将拒绝被陷害

查看此 article on bypassing CSP 了解更多信息。 POC 使用了一个创意黑客:

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

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

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

CSP headers should be present on all the pages, event on the error pages returned by the web-server