style-src 不显式配置即等效于 'none',所有 css(含内联样式、@import、link)均被拦截;它不继承 default-src,必须独立声明,且仅支持 nonce/hash 的 http 响应头方式,不支持 meta 标签。

style-src 不配等于全拒,不是继承 default-src
不显式配置 style-src,浏览器会按空策略处理(等效于 style-src 'none'),所有 CSS 都被拦截——包括 <style></style> 块、style 属性、@import 和 <link rel="stylesheet">。很多人误以为写了 default-src 'self' 就够了,但 CSP 规范明确要求 style-src 必须独立声明,它不继承 default-src。
常见翻车现象:
- 页面白屏或样式丢失,控制台报
Refused to apply inline style或Refused to load the stylesheet - Vue/React 中
styled-components或emotion动态注入的<style></style>被静默丢弃 -
<meta http-equiv="Content-Security-Policy">里配了style-src,但 nonce/hash 不生效(<meta>不支持 nonce/hash)
放行外部 CSS 的正确写法:域名粒度,不带路径
style-src 白名单必须精确到协议+域名+端口,不能带路径或通配符。例如 https://cdn.jsdelivr.net 合法,https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css 或 https://*.jsdelivr.net 都无效。
实操要点:
- 多个 CDN 用空格分隔:
style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net - HTTP 和 HTTPS 视为不同源,需分别列出(如同时支持 HTTP 调试,加
http://fonts.googleapis.com) - 禁用
style-src https:这种宽泛写法——它允许任意 HTTPS 域名,等于开放白名单给全网 -
@import url('https://...')和background: url('https://...')中的 URL 同样受style-src约束,不是connect-src管
内联样式怎么安全放行?别用 unsafe-inline
'unsafe-inline' 会让所有 <style></style> 和 style="..." 绕过检查,彻底废掉 CSP 对 CSS 注入的防护能力。真正可用的安全方案只有两个:
-
'nonce-xxx':服务端每次响应生成唯一随机值(不可预测、不可重用),在响应头中写style-src 'self' 'nonce-abc123',HTML 中对应标签加nonce="abc123"(如<style nonce="abc123">:root { --color: red }</style>) -
'sha256-xxx':对静态<style></style>内容做哈希(如echo -n ":root { --color: red }" | openssl dgst -sha256 -binary | openssl enc -base64),填入style-src 'self' 'sha256-xxx';但 CI/CD 中 CSS 变更后必须同步更新哈希,否则样式失效
注意:strict-dynamic 对 style-src 完全无效,加了也白加,浏览器直接忽略。
CSS 变量(--*)本身不触发 CSP,但注入方式会
--primary 这类自定义属性定义和读取不会触发 style-src 检查,CSP 不管变量内容,只管“样式从哪来”。真正被拦的是动态注入行为:
-
el.setAttribute('style', '--c: red; color: var(--c)')→ 触发style-src检查(因属内联样式) -
document.head.innerHTML += '<style>:root { --t: dark }</style>'→ 触发style-src检查(因属内联<style></style>)
安全做法:
- 把
:root变量定义写进外部 CSS 文件(满足style-src 'self'即可) - 用
CSSStyleSheet.insertRule()动态追加规则(不走字符串解析,不触发 CSP) - 本地调试时若用
file://加载,'self'实际指向about:blank或空源,<style></style>会被丢——此时必须显式加'unsafe-inline'临时调试,上线前删掉
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











