内容安全策略 CSP 是 HTTP 响应头,允许站点声明“脚本/样式/图片等资源的合法来源白名单”,即使 XSS 注入发生也能限制脚本能加载执行的来源;配合 HSTS、X-Content-Type-Options、X-Frame-Options 等安全头,浏览器侧防御得到系统性加固。它替代不了输出编码,而是其上一层强有力的兜底。
第六幕的第二个哨所立在“浏览器侧”。服务器管不了攻击者往页面塞了什么,但能告诉浏览器“哪些来源的脚本/资源我才认”。这道命令式的护栏能在输出编码漏网的时刻,再压一次脚本的执行空间。
CSP 通过响应头声明策略,用指令与来源白名单描述“本页可以加载哪些资源”。最核心的 script-src 决定允许执行脚本的来源:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com
上面写的是:脚本只能来自本域或指定 CDN,其他来源一律不执行;default-src 'self' 作为其他资源类型的兜底。攻击者内联到页面里的 <script>alert(1) 不在 script-src 白名单内,会被浏览器直接禁止执行——即使它成功注入进了 DOM。
威力:它是 XSS 出色的兜底。输出编码漏一处,CSP 仍能阻止恶意脚本执行或加载外部资源(外连的窃密脚本,如把 Cookie 传给攻击者服务端,被 connect-src 限制)。
代价:CSP 一旦配严会误伤正常业务——第三方统计、支付 SDK、动态内联脚本都可能被挡。而为了迁就业务采用 'unsafe-inline'、'unsafe-eval'、* 通配,会把策略的有效性大幅稀释。

max-age 带秒数,includeSubDomains 生效)。四组头各有侧重,合起来把浏览器的防护面铺到传输、资源、嵌入与引荐四个方向。
*、unsafe-inline、unsafe-eval 一劳永逸式放宽。💡 关键直觉:给 CSP 配“报告模式”相当于先试运行再正式生效。把违规报告当成你代码里 XSS 点的免费扫描结果,往往是安全投入里回报最高的几行配置之一。
背景:一个已部署页面的演示站,输出编码漏网造成一处 XSS 可注入。操作一:不加 CSP 时注入 <script> 观察执行;操作二:加 script-src 'self' 后注入同样载荷。结果:CSP 下脚本被浏览器拒绝执行。解读:CSP 在编码漏网的时刻兜了底。变式:体检验证 unsafe-inline 会让内联注入恢复执行,并分别看 X-Content-Type-Options 对上传文件、X-Frame-Options 对 iframe 嵌入的效果,理解各头各自守哪一门。
不用手工猜,CSP 的 report 指令能自动把“哪些违规被拦截”上报来源。开 Content-Security-Policy-Report-Only(只报告不拦截)加 report-uri/report-to,跑一段时间把收集到的违规记录当 XSS 探测结果读:某个本不该加载的外部域频繁出现在报告里,多半是页面里被人塞了带毒脚本或外连资源;正常业务被自己的合法脚本源误伤,报告也会如实呈现。这一来,CSP 从“防守姿态的命令”变成“持续的飞行监测器”——它让你在攻击真正生效前就看到浏览器侧哪里在亮红灯,是主动防御里投入产出很划算的一环。等报告趋向干净,再把 Report-Only 切正式策略就好。
安全头不是一个一个孤立加的,它们有协同也有对撞。举例:HSTS 把域钉在 HTTPS 上,CSP 再把脚本来源收紧,nosniff 防止上传文件被当脚本解析,三个头合起来才覆盖“传输-执行-类型”三段;而 CSP 与 X-Frame-Options 都有防嵌 frame 的能力,配置时以 CSP 的 frame-ancestors 为准、把 X-Frame-Options 当冗余即可,别重复冲突。所以加头不是“把列表补满”,而是画一张“头→防护方向→由哪层负责”的小地图,一眼看出哪个方向缺了、哪两个头职责重叠,避免冗余或互相打架,也让排查时知道该看哪。