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



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

然而,CSP规范似乎表明,在HTML页面加载后,同一上下文中的任何其他CSP规则都将被丢弃而无效。这在我的CSP工作模式中是有意义的,但如果OWASP推荐它,那么我肯定错过了一些东西。

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

在HTML页面已经加载并且<main"CSP已经评估过了吗?>

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

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

有谁能解释一下,在HTML页面已经加载和"main"CSP已经评估过了吗?这在浏览器中是如何工作的?

加上上面的正确答案,帧通常用于CSP旁路。如果一个帧被允许进入页面(没有被CSP阻塞),这个帧有它自己的CSP作用域。所以,如果你为数据创建了一些API——你不希望允许它被设置为一个帧,因为它可以被用来绕过原始的CSP(用于数据泄露作为一个例子)。

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

有关更多信息,请参阅绕过CSP的文章。POC使用了一个创造性的hack:

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

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

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

CSP报头应该出现在所有页面上,事件在web服务器返回的错误页面

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

在加载时读取API或页面的CSP标头。它不是事后才发生的事情。"main"CSP是不相关的,因为它是帧中为自己发送CSP的URI。浏览器仅通过该URI

执行frame-ancestor 'none'请求。

frame-ancestors指令限制了可以使用frame、iframe、object或embed嵌入资源的url。资源可以使用这个指令来避免被嵌入到潜在的敌对环境中的风险,从而避免许多UI redress [uissecurity]攻击。

引用
CSP框架祖先
点击劫持防御小抄
内容安全策略
Web Sec指令框架祖先

最新更新