Content-Security-Policy header 是否仅适用于 text/html Content-Type?

Is Content-Security-Policy header applicable only for text/html Content-Type?

来自 OWASP 的网站 https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html:

Send a Content-Security-Policy HTTP response header from your web server.

Content-Security-Policy: ...

Using a header is the preferred way and supports the full CSP feature set. Send it in all HTTP responses, not just the index page.

我不明白这怎么可能是真的,因为可以通过在 HTML 中使用元标记来设置 Content-Security-Policy。 我也看不出该政策如何适用于 HTML 页以外的任何内容。

有谁知道为什么要做出上述声明,以及仅发送 HTTP header Content-Security-Policy 以获取 text/html 响应是否安全?

顺便说一句,政策太大了,我想发送尽可能少的字节。

这仍然是未正式指定的内容,对此仍有一些争论:https://github.com/w3c/webappsec/issues/520

这里一般有两个参数:

一方面,一些其他文件类型(XML、PDF,甚至可能是 SVG)可以从 CSP 中受益,并且任何资源都可以通过右键单击并在单独的选项卡中打开来成为页面。

另一方面,CSP 可能会变得很大并且通常为 HTML 页编写。所以发送其他资源有点浪费,而且大部分资源都不相关。

正确的答案(如上文所建议的)可能是对所有非HTML 响应采用简化且非常严格的 CSP。

但我认为对于大多数人来说,仅在 HTML 上安装它就足够了,并且可以带来 CSP 的大部分好处。话又说回来,CSP 是一项先进的技术,所以如果能做到这一点,那为什么不正确地做呢?

Using a header is the preferred way and supports the full CSP feature set.

I don't understand how that could be true as it is possible to set the Content-Security-Policy by using a meta tag in the HTML.

  1. 不支持元标记内的指令:
  • report-toreport-uri
  • frame-ansectors
  • sandox
  1. 另外meta标签不支持Content-Security-Policy-Report-Only功能,只支持Content-Security-Policy.

  2. 所有在 HTML 代码中的元标记之前开始加载的资源不受 CSP 影响。恶意脚本可以作为 <head> 部分的第一项注入,就在元标记

    之前
  3. nonce-value 暴露在元标记中,因此可以很容易地被脚本窃取和重用。

  4. 使用meta标签只能为HTML页设置CSP,但CSP适用于XML页的XSLT,以及一些其他类型的内容(见下文)。

因此确实 HTTP header 是 传送 CSP 的首选方式 并且通过元标记使用 CSP 不允许您使用 完整的 CSP功能集.

Send it in all HTTP responses, not just the index page.

I also don't see how the policy can apply to anything else but HTML pages.

规范的想法略有不同 - 您应该将包含 HTML 内容的任何响应页面发送给 CSP,不仅 200 OK,甚至 404 Not found 403 Access Forbidden
因为这些页面可以访问 cookie,可以在未被 CSP 覆盖的页面中窃取。

CSP 不仅应用于 HTML 页面,还应用于 XML-pages 中的 XSLT,应用于工作人员的外部 javascripts 文件(在 Firefox). Also frame-ancestors directive of CSP HTTP header applies to any content (JPEG/GIF/PNG/PDF/MP4/etc) intended to be embedded into iframe, see the nitty-gritty here.