HTTPQUERY
English

Content-Security-Policy

用法

Content-Security-Policy(CSP)头让站点管理员能够精细控制资源加载。通过声明一项策略,服务器指示浏览器仅从获批准的来源加载脚本、样式、图像、字体以及其他资源。任何不匹配该策略的资源都会被阻止,浏览器还会报告违规行为。

一项策略由一个或多个以分号分隔的指令组成。每个指令命名一种资源类型,并列出该资源类型允许的来源。

Content-Security-Policy: <directive> <source>; <directive>
  <source>

先以仅报告模式部署新策略是一种常见做法。Content-Security-Policy-Report-Only 头采用相同语法,但只记录违规而不阻止资源,让管理员在强制执行前先对策略进行测试。

Fetch 指令

Fetch 指令控制特定资源类型的加载来源。

default-src

default-src 指令作为所有其他 fetch 指令的回退。当某个具体的 fetch 指令缺失时,浏览器回退到 default-src。

Content-Security-Policy: default-src 'self'

script-src

script-src 指令限制 JavaScript 执行的来源。基于 nonce 和基于 hash 的允许列表比基于主机的规则提供更强的防护。

script-src-elem

script-src-elem 指令专门作用于

script-src-attr

script-src-attr 指令管理诸如 onclick 和 onload 等内联事件处理器,与

style-src

style-src 指令指定 CSS 样式表的有效来源,包括内联样式和外部样式表链接。

style-src-elem

style-src-elem 指令作用于

style-src-attr

style-src-attr 指令管理通过 style 属性直接应用到 DOM 元素上的内联样式。

img-src

img-src 指令指定图像和网站图标的有效来源。

connect-src

connect-src 指令限制可通过脚本接口访问的 URL,包括 fetch()、XMLHttpRequest、WebSocket 和 EventSource。

font-src

font-src 指令指定通过 @font-face 加载的字体的有效来源。

frame-src

frame-src 指令指定由 和

media-src

media-src 指令指定

object-src

object-src 指令限制 元素的来源( 是已从 HTML 规范中移除的遗留元素)。建议将其设为 ‘none’,因为这些元素很少需要用到。

child-src

child-src 指令定义 web worker 和嵌套浏览上下文的允许来源。当存在更具体的 frame-src 和 worker-src 指令时,它们会覆盖 child-src。

worker-src

worker-src 指令作用于 Worker、SharedWorker 和 ServiceWorker 脚本。

manifest-src

manifest-src 指令指定 web 应用清单文件的有效来源。

fenced-frame-src

fenced-frame-src 指令指定加载到 元素中的嵌套浏览上下文的有效来源。当缺失时,浏览器回退到 frame-src,然后再回退到 default-src。

Document 指令

Document 指令管理文档环境的属性。

base-uri

base-uri 指令限制 元素中允许的 URL,防止攻击者更改相对链接的基础 URL。

sandbox

sandbox 指令对页面施加与

Navigation 指令控制用户和表单发送请求的目标。

form-action

form-action 指令限制可作为表单提交目标的 URL。

frame-ancestors

frame-ancestors 指令指定允许使用 、

navigate-to 指令曾被提议用于限制文档通过任何机制被允许导航到的 URL。该指令已从 CSP Level 3 规范中移除,且从未在任何生产环境浏览器中发布。

Reporting 指令

Reporting 指令控制违规报告行为。

report-to

report-to 指令指定由 Reporting-Endpoints 头定义的报告分组名称。违规报告会被发送到与该命名分组关联的端点。

report-uri

report-uri 指令将违规报告发送到指定的 URL。该指令正在被 report-to 取代,但为向后兼容仍被广泛部署。

upgrade-insecure-requests

upgrade-insecure-requests 指令指示浏览器将页面上所有 HTTP URL 视为 HTTPS。在从 HTTP 迁移到 HTTPS 的过程中,当许多资源仍引用不安全的 URL 时,这一点很有价值。

require-trusted-types-for

require-trusted-types-for 指令为 DOM XSS 注入汇聚点强制执行 Trusted Types 策略,要求使用类型化对象而非字符串。

trusted-types

trusted-types 指令指定一份 Trusted Types 策略名称的允许列表,限制页面可创建的策略。

来源值

指令接受用于定义资源加载位置的来源表达式。

‘self’

匹配当前源(相同的方案、主机和端口)。不包括子域名。

‘none’

阻止该指令的所有来源。指定类型的资源一律不加载。

‘unsafe-inline’

允许内联

‘unsafe-eval’

允许通过 eval()、Function() 及类似结构进行动态代码求值。

‘unsafe-hashes’

允许由其 hash 标识的特定内联事件处理器,而不启用所有内联脚本。

‘strict-dynamic’

将信任扩展到由已受信任脚本加载的脚本。与基于 nonce 的策略结合使用时,无需再逐个将每个脚本主机加入允许列表。

‘nonce-*’

由服务器为每个响应生成的加密 nonce(一次性使用的数字)。策略中的 nonce 值需与

Content-Security-Policy: script-src 'nonce-abc123'

‘sha256-’、‘sha384-’、‘sha512-*’

内联脚本或样式内容的 hash。浏览器计算每个内联块的 hash,并将结果与允许列表中的 hash 进行比较。

host-source

指定允许来源的主机或 URL 模式。支持子域名通配符(*.example.re)、特定端口(example.re:443)以及路径前缀(example.re/scripts/)。

scheme-source

诸如 https: 或 data: 的方案,允许所有通过该命名协议提供的资源。

‘report-sample’

将 ‘report-sample’ 关键字添加到 script-src 或 style-src 值中,可要求浏览器在违规报告中包含一小段违规代码样本。这有助于定位有问题的内联脚本或样式。

示例

一项仅允许来自同源资源的严格策略会阻止所有内联脚本和外部资源加载。

Content-Security-Policy: default-src 'self'

一项对脚本和图像使用独立规则的策略。脚本仅从同源加载,而图像还可从专用的图像 CDN 加载。

Content-Security-Policy: default-src 'self';
  img-src 'self' images.example.re

一项针对脚本的基于 nonce 的策略。每次页面加载都会生成一个全新的 nonce,只有携带匹配 nonce 属性的

Content-Security-Policy: script-src 'nonce-r4nd0m';
  style-src 'self'

一项将 ‘strict-dynamic’ 与 nonce 结合的策略。受信任的脚本可以自由加载其他脚本,无需逐个基于主机加入允许列表。

Content-Security-Policy: script-src 'strict-dynamic'
  'nonce-r4nd0m'

一项在强制执行规则的同时将违规上报到某个端点以供监控的策略。

Content-Security-Policy: default-src 'self';
  report-to csp-violations

故障排查

CSP 违规会以 “Refused to…” 消息的形式出现在浏览器控制台中,并附带被阻止的资源 URI 以及导致阻止的指令。

添加 CSP 后内联脚本被阻止。浏览器记录 Refused to execute inline script because it violates the following Content Security Policy directive: “script-src …”。默认策略会阻止所有内联

内联样式被阻止。当 style-src 不包含 ‘unsafe-inline’ 或匹配的 nonce/hash 时,控制台会显示 Refused to apply inline style。在运行时注入样式的框架会触发此违规。向 style-src 添加 nonce,或在过渡到基于 nonce 的样式期间使用 ‘unsafe-inline’。

因指令中缺少域名而阻止外部资源。出现 Refused to load the script 或 Refused to connect 错误意味着该资源来源未在相关指令中列出。打开浏览器控制台,从违规消息中识别被阻止的来源,并将其添加到正确的指令中(script-src、img-src、connect-src 等)。同时检查 default-src,因为缺失的指令会回退到默认值。

eval() 默认被阻止。依赖 eval()、new Function() 或模板编译器的库会触发 Refused to evaluate a string as JavaScript。向 script-src 添加 ‘unsafe-eval’ 可恢复该功能,但会削弱策略。应尽可能重构代码以避免使用 eval()。

Google Tag Manager 或分析脚本在 CSP 下失效。标签管理器会动态注入脚本,每个注入的脚本都需要 nonce 或主机允许列表条目。将 GTM 域名(https://www.googletagmanager.com)添加到 script-src,并将 https://www.google-analytics.com 添加到 connect-src 和 img-src。对于基于 nonce 的策略,使用 ‘strict-dynamic’,使由受信任的 GTM 脚本加载的脚本无需单独的主机条目即可继承信任。

在浏览器控制台中调试违规。打开 DevTools 并查看 Console 选项卡中的 CSP 违规消息。每条消息都会指出被阻止的 URI、被违反的指令以及完整策略。在 Chrome 中,Network 选项卡会用 (blocked:csp) 状态标记被阻止的请求。Firefox 在 Console 和 Network 面板中都提供类似的细节。

使用 Report-Only 模式安全地测试策略。首先使用 Content-Security-Policy-Report-Only 头部署策略。它会记录违规而不阻止任何资源。监控违规报告,修复缺失的来源,待报告流干净后再切换到强制执行的 Content-Security-Policy 头。