CSP (内容安全策略)
约 4 分钟阅读
最后更新: 2026-02-25
什么是 CSP (Content Security Policy)
CSP (Content Security Policy) 是一种 HTTP 响应头,允许服务器控制网页可以加载资源 (脚本、样式表、图片、字体等) 的来源。由于浏览器会阻止加载或执行 CSP 不允许的资源,因此可以大幅缓解 XSS (跨站脚本攻击) 的危害。
XSS 的根本防御措施是输出转义,但实现上的遗漏无法完全消除。CSP 作为纵深防御的一层,发挥着「即使存在 XSS 漏洞,也不让攻击者的脚本执行」的作用。它是安全头中最强大且最复杂的头之一。
主要指令
CSP 由多个指令组成,为每种资源类型指定允许的来源。
default-src:其他指令未明确指定的资源的默认策略。default-src 'self'仅允许来自同源的资源script-src:控制 JavaScript 的加载来源。XSS 防御的核心指令。避免使用'unsafe-inline',推荐使用 nonce 或 hashstyle-src:控制 CSS 的加载来源img-src:控制图片的加载来源connect-src:控制 fetch、XMLHttpRequest、WebSocket 的连接目标font-src:控制 Web 字体的加载来源frame-src:控制 iframe 的嵌入来源。也与点击劫持防御相关frame-ancestors:控制哪些父页面源可以将本站嵌入 iframe。是X-Frame-Options的后继
源值的指定方式
'self':同源'none':全部阻止'nonce-{random}':仅允许具有特定 nonce 值的内联脚本/样式'strict-dynamic':也允许由 nonce 许可的脚本动态加载的脚本- 具体域名:
https://cdn.example.com
分阶段部署步骤
CSP 的部署应循序渐进,避免破坏现有站点。
步骤 1:使用 Report-Only 模式监控
使用 Content-Security-Policy-Report-Only 头可以检测并报告策略违规,但不会阻止资源。首先使用此模式了解站点当前加载了哪些资源。
步骤 2:制定基础策略
根据报告分析结果,将必要的资源来源添加到白名单。从宽松的策略开始,逐步收紧。
步骤 3:生产环境部署与持续监控
切换到 Content-Security-Policy 头进行生产部署。通过 report-uri 或 report-to 指令持续收集违规报告,应对误报和新的资源需求。
推荐的严格策略示例
default-src 'none'; script-src 'self' 'nonce-{random}' 'strict-dynamic'; style-src 'self' 'nonce-{random}'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
此策略通过 nonce 控制内联脚本,并使用 'strict-dynamic' 允许动态加载的脚本。
CSP 与其他安全头的协同
CSP 本身已很强大,但与其他安全头结合可以构建更坚固的防御。
- 与 HSTS 配合:强制 HTTPS,防止通过中间人攻击篡改 CSP 头。HTTPS 是发挥 CSP 最大效果的前提
X-Content-Type-Options: nosniff:防止 MIME 类型嗅探,阻止不应被解释为脚本的资源执行- 与 CORS 的关系:CSP 控制资源的加载来源,CORS 控制跨源请求的访问权限。两者是互补关系
CSP 的部署有初始成本,但能大幅提升对 XSS 和点击劫持的防御能力。在新项目中从开发初期就将 CSP 纳入设计,比后期引入可以大幅降低成本。
常见误解
- 设置了 CSP 就不需要 XSS 防御措施了
- CSP 是缓解 XSS 危害的纵深防御的一层,不能替代 XSS 的根本防御措施 (输出转义)。CSP 的绕过技术也在被研究中,建议同时实现输出转义和 CSP。
- CSP 配置太难,小型站点不需要
- 即使是小型站点也存在 XSS 风险。从最小策略 (例如 default-src 'self'; script-src 'self') 开始,部署很容易。可以通过 Report-Only 模式确认影响,逐步收紧。