概念
HTTP 响应标头 Content-Security-Policy
允许站点管理者控制用户代理能够为指定的页面加载哪些资源。除了少数例外情况,设置的政策主要涉及指定源服务器和脚本端点。这将帮助防止跨站脚本攻击。
解释:哪些文件可以在网站上运行
注意语法规则标点符号使用
HTTP
Content-Security-Policy: script-src 'self' https://safe-external-site.com; style-src 'self'
Fetch 指令
Fetch 指令控制指定资源类型可以从哪里加载。
default-src
: 默认策略,没有具体指定策略default-src 'self' trusted-domain.com
img-src
: 图片img-src 'self' img.mydomain.com
font-src
: 字体object-src
:<object>
、<embed>
media-src
: 视频、音频script-src
脚本style-src
css
Fetch 指令语法
- 'none' :不匹配任何内容
- 'self':匹配当前主机域(同源,即主机和端口)。但是,不要匹配子域
- 'unsafe-inline':允许内联 JavaScript 和 CSS,尽量不要使用,nonce 代替 unsafe-inline
- 'unsafe-eval':允许动态文本用于 JavaScript eval
- domain.example.com:允许从指定域加载资源。要匹配任何子域,请使用 * 通配符,例如 *.example.com
- https: 或 ws:: 仅允许通过 HTTPS 或 WebSocket 加载资源
- nonce-{token}:允许包含相同 nonce 属性值的内联脚本或 CSS
- 'strict-dynamic' 关键字使得通过 nonce 或 hash 信任的脚本扩展到此脚本动态加载的脚本,例如通过使用
Document.createElement()
创建新的<script>
标签,然后通过Node.appendChild()
将其插入文档中
使用
- 服务器
node
、nginx
- Nginx 中可以使用内置变量的 $request_id 作为唯一 id,而当 nginx 版本不支持时,则可以借助 lua 去生产一个 uuid
- 接着通过 Nginx 的 sub_filter NONCE_TOKEN 'id' 将页面中的 NONCE_TOKEN 占位符替换为 id,或者使用 lua 进行替换
- 最后使用 add_header Content-Security-Policy "script-src 'nonce-{id}'" 添加对应的 CSP 返回头
HTTP
Content-Security-Policy: script-src 'nonce-5fAifFSghuhdf' 'strict-dynamic'
- html meta 标签
html
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://safe-external-site.com">
HTTP Content-Security-Policy-Report-Only
响应头允许 web 开发人员通过监测 (但不强制执行) 政策的影响来尝试政策。这些违反报告由 JSON 文档组成通过一个 HTTP POST 请求发送到指定的 URI。
css
Reporting-Endpoints: name-of-endpoint="后端请求地址"
Content-Security-Policy: default-src 'self'; report-to name-of-endpoint