研发安全 | 如何用好内容安全策略(CSP)?
字数 2317 2025-08-20 18:18:23

内容安全策略(CSP)全面指南

CSP概述

内容安全策略(Content-Security-Policy, CSP)是一种重要的Web安全机制,通过服务器端注入CSP头,浏览器能够帮助用户降低XSS、点击劫持和跨站数据泄露等安全风险。

CSP本质

  • 白名单制度:明确告诉客户端哪些外部资源可以加载和执行
  • 浏览器执行:实现和执行全部由浏览器完成,开发者只需提供配置
  • 纵深防御:即使攻击者发现漏洞,也难以成功注入恶意脚本
  • 报告机制:通过态势感知和CSP报告机制可及时发现攻击行为

主要配置指令

指令 功能描述
default-src 定义大多数资源的默认源
script-src 指定允许加载和执行的脚本源
style-src 指定允许加载和应用的样式表源
img-src 指定允许加载的图像源
font-src 指定允许加载的字体源
media-src 指定允许加载的媒体资源(视频/音频)源
object-src 指定允许加载的插件(如Flash)源
frame-src 指定允许在iframe中加载的资源源
child-src 指定允许作为子资源加载的源
connect-src 指定允许进行网络连接(AJAX请求)的源
form-action 指定表单提交的允许目标源
frame-ancestors 指定允许嵌入当前页面的祖先页面源
manifest-src 指定允许加载的Web应用程序清单源
worker-src 指定允许加载的Web Workers源
base-uri 指定页面中<base>标签的允许源
plugin-types 指定允许加载的插件类型
sandbox 为页面提供安全沙箱环境,限制脚本、表单提交等行为
navigate-to 指定允许页面导航到的源
prefetch-src 指定允许预加载的资源源
report-uri 指定CSP违规报告发送到的URI
report-to 指定CSP违规报告发送到的报告端点名称
upgrade-insecure-requests 指示浏览器将所有HTTP请求升级为HTTPS
block-all-mixed-content 阻止所有混合内容(HTTPS页面上加载HTTP资源)
referrer 控制发送到请求中的Referer头部
policy-uri 提供指向当前策略的URI,供浏览器在需要时获取

CSP实施方式

1. HTTP Header方式(首选)

Content-Security-Policy: 策略
Content-Security-Policy-Report-Only: 策略

2. HTML Meta标签方式

<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">

注意

  • 如果HTTP头与Meta定义同时存在,优先采用HTTP中的定义
  • 如果浏览器已为当前文档执行了CSP策略,会跳过Meta定义
  • 如果meta标签缺少content属性,同样会跳过

CSP策略语法

  • 多个指令之间用英文分号(;)分割
  • 多个指令值用英文空格分割
  • 避免重复定义同一指令(后定义的会被忽略)

正确与错误示例

错误写法(第二个指令会被忽略):

Content-Security-Policy: script-src https://host1.com; script-src https://host2.com

正确写法

Content-Security-Policy: script-src https://host1.com https://host2.com

CSP策略示例

  1. 限制所有外部资源只能从当前域名加载:
Content-Security-Policy: default-src 'self'
  1. 复杂策略示例:
Content-Security-Policy: 
  default-src https://host1.com https://host2.com;
  frame-src 'none'; 
  object-src 'none'
  1. 带报告功能的策略:
Content-Security-Policy: 
  default-src 'self';
  report-uri /my_amazing_csp_report_parser;

CSP指令值说明

指令值 说明
'self' 表示同源,只允许从当前域名加载资源
https://example.com 明确指定允许加载资源的域名
'none' 禁止加载任何资源
'unsafe-inline' 允许内联脚本/样式(降低安全性)
'unsafe-eval' 允许eval等动态代码执行(降低安全性)
'strict-dynamic' 信任由已执行脚本动态创建的脚本

CSP自查表

指令 示例 说明
default-src default-src 'self'; 定义大多数资源的默认允许源
script-src script-src 'self' https://cdn.com; 指定允许加载和执行脚本的源
style-src style-src 'self' 'unsafe-inline'; 指定允许加载的样式表源

最佳实践

  1. 从严格策略开始:初始配置尽可能严格,逐步放宽
  2. 使用报告模式:先使用Content-Security-Policy-Report-Only测试策略
  3. 避免内联脚本:尽量不使用'unsafe-inline'
  4. 限制外部资源:明确指定可信的外部域名
  5. 定期审查:根据CSP报告定期审查和更新策略
  6. HTTPS优先:配合upgrade-insecure-requestsblock-all-mixed-content使用

注意事项

  • CSP不是万能的,不能替代其他安全措施
  • 如果攻击者控制了白名单内的可信主机,CSP可能失效
  • 复杂的网站可能需要逐步实施CSP
  • 某些旧版浏览器可能不完全支持所有CSP特性
内容安全策略(CSP)全面指南 CSP概述 内容安全策略(Content-Security-Policy, CSP)是一种重要的Web安全机制,通过服务器端注入CSP头,浏览器能够帮助用户降低XSS、点击劫持和跨站数据泄露等安全风险。 CSP本质 白名单制度 :明确告诉客户端哪些外部资源可以加载和执行 浏览器执行 :实现和执行全部由浏览器完成,开发者只需提供配置 纵深防御 :即使攻击者发现漏洞,也难以成功注入恶意脚本 报告机制 :通过态势感知和CSP报告机制可及时发现攻击行为 主要配置指令 | 指令 | 功能描述 | |------|----------| | default-src | 定义大多数资源的默认源 | | script-src | 指定允许加载和执行的脚本源 | | style-src | 指定允许加载和应用的样式表源 | | img-src | 指定允许加载的图像源 | | font-src | 指定允许加载的字体源 | | media-src | 指定允许加载的媒体资源(视频/音频)源 | | object-src | 指定允许加载的插件(如Flash)源 | | frame-src | 指定允许在iframe中加载的资源源 | | child-src | 指定允许作为子资源加载的源 | | connect-src | 指定允许进行网络连接(AJAX请求)的源 | | form-action | 指定表单提交的允许目标源 | | frame-ancestors | 指定允许嵌入当前页面的祖先页面源 | | manifest-src | 指定允许加载的Web应用程序清单源 | | worker-src | 指定允许加载的Web Workers源 | | base-uri | 指定页面中 <base> 标签的允许源 | | plugin-types | 指定允许加载的插件类型 | | sandbox | 为页面提供安全沙箱环境,限制脚本、表单提交等行为 | | navigate-to | 指定允许页面导航到的源 | | prefetch-src | 指定允许预加载的资源源 | | report-uri | 指定CSP违规报告发送到的URI | | report-to | 指定CSP违规报告发送到的报告端点名称 | | upgrade-insecure-requests | 指示浏览器将所有HTTP请求升级为HTTPS | | block-all-mixed-content | 阻止所有混合内容(HTTPS页面上加载HTTP资源) | | referrer | 控制发送到请求中的Referer头部 | | policy-uri | 提供指向当前策略的URI,供浏览器在需要时获取 | CSP实施方式 1. HTTP Header方式(首选) 2. HTML Meta标签方式 注意 : 如果HTTP头与Meta定义同时存在,优先采用HTTP中的定义 如果浏览器已为当前文档执行了CSP策略,会跳过Meta定义 如果meta标签缺少content属性,同样会跳过 CSP策略语法 多个指令之间用英文分号( ; )分割 多个指令值用英文空格分割 避免重复定义同一指令(后定义的会被忽略) 正确与错误示例 错误写法 (第二个指令会被忽略): 正确写法 : CSP策略示例 限制所有外部资源只能从当前域名加载: 复杂策略示例: 带报告功能的策略: CSP指令值说明 | 指令值 | 说明 | |--------|------| | 'self' | 表示同源,只允许从当前域名加载资源 | | https://example.com | 明确指定允许加载资源的域名 | | 'none' | 禁止加载任何资源 | | 'unsafe-inline' | 允许内联脚本/样式(降低安全性) | | 'unsafe-eval' | 允许eval等动态代码执行(降低安全性) | | 'strict-dynamic' | 信任由已执行脚本动态创建的脚本 | CSP自查表 | 指令 | 示例 | 说明 | |------|------|------| | default-src | default-src 'self'; | 定义大多数资源的默认允许源 | | script-src | script-src 'self' https://cdn.com; | 指定允许加载和执行脚本的源 | | style-src | style-src 'self' 'unsafe-inline'; | 指定允许加载的样式表源 | 最佳实践 从严格策略开始 :初始配置尽可能严格,逐步放宽 使用报告模式 :先使用 Content-Security-Policy-Report-Only 测试策略 避免内联脚本 :尽量不使用 'unsafe-inline' 限制外部资源 :明确指定可信的外部域名 定期审查 :根据CSP报告定期审查和更新策略 HTTPS优先 :配合 upgrade-insecure-requests 和 block-all-mixed-content 使用 注意事项 CSP不是万能的,不能替代其他安全措施 如果攻击者控制了白名单内的可信主机,CSP可能失效 复杂的网站可能需要逐步实施CSP 某些旧版浏览器可能不完全支持所有CSP特性