← 返回题目列表

CSP 内容安全策略是什么?它能防什么?

高频 中等 第 10 / 26 题 更新于 2026/07/28
前端安全CSPXSS安全策略

简化版

CSP 是浏览器提供的内容安全策略,通过 HTTP 响应头限制页面可以加载哪些脚本、样式、图片、字体等资源。它能降低 XSS、数据注入和恶意资源加载风险,但不能替代输入校验和输出转义。

详细版

CSP 常通过响应头配置:

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

常见指令:

  • default-src:默认资源来源。
  • script-src:脚本来源。
  • style-src:样式来源。
  • img-src:图片来源。
  • connect-src:接口请求来源。
  • frame-ancestors:限制谁能嵌入当前页面。

CSP 可以禁止内联脚本、限制第三方脚本来源、上报违规行为。它是重要防线,但配置过严可能影响业务资源加载。

完整版教学

一、CSP 的核心思想

XSS 的危险在于攻击者让页面执行了不该执行的脚本。CSP 的思路是提前告诉浏览器:“只有这些来源的脚本能执行,其它都不行。”

这样即使页面出现了注入点,攻击脚本也可能因为违反策略而无法执行。

二、常见配置

最基础的配置是只允许同源资源:

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

如果业务需要加载 CDN 脚本,就要显式加入可信域名。

对于脚本安全,可以减少或禁止 'unsafe-inline'。如果确实需要内联脚本,可以考虑 nonce 或 hash 机制。

三、CSP 的边界

CSP 不能修复所有安全问题。它不能替代服务端鉴权,也不能替代富文本过滤。

如果策略配置过松,比如允许所有脚本来源,效果会很弱。配置过严又可能导致页面资源加载失败。因此它需要结合业务资源清单逐步上线。

四、面试追问与工程落地

面试官可能问:“CSP 如何灰度上线?”

可以先使用 Content-Security-Policy-Report-Only,只上报违规但不拦截资源。观察一段时间后修正规则,再切换到正式拦截模式。

工程中要把第三方脚本纳入治理,避免任何业务都随意加外链脚本。

五、nonce、hash 与严格策略的机制

仅按域名列白名单可能仍信任被攻陷的第三方脚本。严格 CSP 更常围绕每次响应生成的 nonce 或静态脚本 hash 建立执行授权:

Content-Security-Policy: script-src 'nonce-r4Nd0mValue' 'strict-dynamic'; object-src 'none'; base-uri 'none'
方式适用场景关键约束
nonceSSR 动态 HTML每个响应重新生成,值不可预测
hash固定内联脚本脚本文本变化就要更新 hash
主机白名单迁移期资源治理受信域被攻陷时风险仍在
'unsafe-inline'兼容旧代码会显著削弱脚本注入防护

nonce 必须由服务端使用足够随机性生成,不能写死或按用户可预测信息计算。给可信入口脚本 nonce 后,strict-dynamic 可让支持它的浏览器信任该脚本动态加载的后续脚本,减少庞大域名名单。

CSP 是浏览器执行层的纵深防线:根治注入仍靠上下文编码和安全 DOM API,CSP 用来限制漏网内容能做什么。

六、灰度、上报和数字化验收

存量站点可先运行 7 天 Content-Security-Policy-Report-Only,统计违反指令、资源地址和页面版本。若每天 100 万次访问产生 5 万条同一扩展插件报告,应在采集端聚合采样,而不是直接放宽策略。

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

验收不只是“页面能打开”:尝试插入无 nonce 的内联脚本应被拦截;合法 nonce 脚本应执行;图片、接口、frame 分别受 img-srcconnect-srcframe-src 控制;页面是否能被嵌入则看 frame-ancestors

报告可能含页面地址等敏感信息,采集端要做权限、保留周期和脱敏。切换正式策略时分页面灰度,并保留回滚能力,避免一次配置错误造成全站白屏。

七、常见误区与追问

  • 误区:配置 CSP 就彻底修复了 XSS。 CSP 是纵深防线,危险 sink 和错误编码仍需从代码中修复。
  • 误区:default-src 'self' 会覆盖所有 CSP 指令。 frame-ancestors 等指令没有该回退,必须单独声明。
  • 误区:nonce 可以写成固定常量复用。 可预测或复用的 nonce 可能被攻击内容利用,应逐响应随机生成。
  • 追问:为什么尽量不使用 'unsafe-inline' 它允许大量内联脚本执行,会重新打开常见注入路径。
  • 追问:hash 与 nonce 怎么选? 固定脚本适合 hash,服务端动态页面通常更适合逐响应 nonce。
  • 追问:Report-Only 会拦截资源吗? 不会,它只报告违规,适合盘点存量依赖和灰度。
  • 追问:CSP 能限制数据外传吗? connect-srcimg-srcform-action 等可缩小通道,但不能替代敏感数据最小化。

八、加强记忆

  1. 先治理:普通文本编码、富文本清洗、安全 DOM API 是根本。
  2. 再约束:CSP 限制脚本、连接、frame 等资源能力。
  3. 严格脚本:动态页用逐响应 nonce,固定内容可用 hash。
  4. 拒绝放水:谨慎使用 unsafe-inline、通配域和过宽 data 源。
  5. 灰度上线:Report-Only 盘点,采样聚合,再分批强制。
  6. 持续验证:合法资源可用、恶意内联被拦、报告可观测且可回滚。