白盒测试时发现CSS注入漏洞,如何验证并修复? Code°佳润 提问于 2026-01-28 14:06:31 阅读 37 安全 在审计前端代码时发现一个动态插入用户CSS样式的功能,像这样: .example { content: attr(data-style); /* 用户提供的样式会直接填充到data-style属性 */ } 用白盒测试工具扫描提示可能存在CSS注入风险,但不确定具体怎么验证。试过过滤尖括号和@import,但测试用例输入 url(javascript:alert(1)) 时仍然能触发弹窗。该怎么正确验证漏洞是否存在?修复时该用CSS转义还是直接禁用危险函数? Web安全测试白盒测试 我来解答 赞 12 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 FSD-雪琪 Lv1 CSS的话,你这个漏洞其实挺典型的,本质是把用户输入直接当成样式解析了,attr(data-style) 这种用法在伪元素里本来就不该用来动态加载完整CSS规则。 先说怎么验证。你试过 url(javascript:alert(1)) 能弹窗,说明已经成功触发了——这就是典型的CSS表达式注入。浏览器解析到 background-image 或 content 属性里的 javascript: 协议时会执行,哪怕是在 data- 属性拼接进来的。你可以再试试这些 payload: url('javascript:alert(document.domain)') 或者通过其他支持 js 协议的属性比如 background、list-style-image 等绕过过滤。即使你过滤了 @import,攻击者根本不需要它,直接用 url() 配合 javascript: 就能完成 XSS。 至于修复,别想着靠转义或者字符串替换来堵漏,太容易被绕过。正确的做法是: 1. 绝对禁止用户控制完整的CSS样式字符串。如果你非要支持自定义样式,应该只允许用户选择预设的 class 名,而不是传一整段 style 字符串。 2. 如果必须接受样式输入,使用白名单机制限制可设置的属性(比如只允许 color、background-color),然后对值做严格校验,比如颜色必须是 hex/rgb 格式。 3. 在插入 DOM 前,用 CSSOM API 逐条解析和过滤,不要用 innerHTML 或 style.cssText 直接写入。 4. 加上 CSP 头,至少设置 style-src 'self',禁用内联样式和 javascript: 协议,这样即使有注入也执行不了。 最根本的:别让用户的内容变成CSS代码,这是原则。你现在这逻辑相当于 eval(cssString),和 eval(jsString) 没区别,危险得很。 回复 点赞 6 2026-02-09 12:01 毓琳 ☘︎ Lv1 这个问题确实挺棘手的,CSS注入有时候比XSS还难防。先说验证方法,你可以试试以下payload: url(javascript:alert('test')) 如果能触发弹窗,那基本可以确认漏洞存在了。因为content属性支持URL格式,而浏览器会尝试加载这个URL,当遇到javascript:协议时就会执行代码。 至于修复方案,常见的做法有两种: 1. **完全禁用动态CSS功能**:如果你觉得这个功能没啥必要,直接移除它是最简单有效的办法。 2. **使用白名单过滤并转义**:如果一定要保留这个功能,建议对用户输入的内容做严格的白名单校验,只允许特定的CSS属性值。同时,可以用正则把危险字符(比如括号、冒号等)替换掉,像这样: function sanitizeCSS(input) { // 移除潜在危险字符 return input.replace(/[():;]/g, ''); } // 使用时 const safeStyle = sanitizeCSS(userInput); element.setAttribute('data-style', safeStyle); 不过说实话,这种过滤方式还是有点冒险,推荐直接用安全的替代方案,比如通过预定义的类名来控制样式,而不是让用户直接输入CSS。 最后提醒一下,千万别只依赖黑名单过滤,那样很容易漏掉某些奇怪的payload。 回复 点赞 6 2026-01-29 21:02 加载更多 相关推荐 1 回答 46 浏览 前端渗透测试中如何防范CSS注入攻击? 我在做安全测试时,发现用户输入的样式能直接渲染到页面上,担心有CSS注入风险。比如下面这段动态生成的CSS: .user-style { background: url(' + userInput +... ❤恒菽 安全 2026-03-01 08:01:19 1 回答 64 浏览 白盒测试时如何判断CSS会不会引发安全问题? 最近在做Web安全的白盒测试,看到项目里有一段动态生成的CSS,担心会不会有XSS风险。虽然CSS本身不能执行JS,但听说某些属性比如url()或者@import可能被利用,是不是真的? 比如下面这段... Mc.莉娜 安全 2026-03-19 05:24:22 2 回答 56 浏览 前端代码审查时如何发现CSS注入风险? 最近在做安全Code Review,看到一段动态拼接CSS的逻辑,担心有注入漏洞。比如用户输入直接插进style标签里,会不会被利用? 我查了资料说CSS本身不像JS那样能执行脚本,但某些属性比如ur... 志红 Dev 安全 2026-03-15 11:18:21 2 回答 29 浏览 前端安全审计时如何防止CSS注入风险? 最近在做项目的安全审计,发现有个用户自定义主题的功能,允许传入CSS字符串动态应用样式。我担心这里会有CSS注入漏洞,比如用户输入恶意代码破坏页面或窃取数据。虽然我用了DOMPurify处理HTML,... UE丶海宇 前端 2026-03-11 11:56:21 2 回答 63 浏览 前端安全审计中如何评估CSS注入风险? 最近在做项目安全自查,发现用户能自定义主题色,但担心CSS注入问题。我用了类似下面的写法,这样安全吗? .user-theme { --primary-color: ${userInput}; bac... 诸葛莉霞 安全 2026-03-05 14:35:18 1 回答 68 浏览 E2E测试中如何正确等待动态加载的CSS动画元素? 我用Cypress写E2E测试时,有个按钮点击后会通过CSS动画淡入一个提示框,但测试经常因为元素还没完全显示就断言失败。我已经试过cy.wait()和cy.get().should('be.visi... 长孙玉萱 前端 2026-03-16 11:56:20 1 回答 26 浏览 Vite 插件里怎么处理 CSS 中的变量注入? 我在写一个 Vite 插件,想在构建时动态往 CSS 里注入一些变量,比如主题色。但试了几次发现 transform 阶段拿到的 CSS 内容没法正确替换,或者替换后样式就乱了。 我用的是 trans... 设计师诗谣 工具 2026-03-06 12:43:20 2 回答 46 浏览 单元测试怎么测CSS样式是否生效? 我写了个按钮组件,想用Jest + Testing Library做单元测试,但不知道怎么验证CSS样式有没有正确应用。比如我给按钮加了hover效果,测试里能检测到吗? 这是我的CSS代码: .my... 新艳 Dev 前端 2026-02-25 18:34:19 1 回答 40 浏览 前端项目里怎么用威胁情报检测恶意CSS注入? 最近在做安全审计,听说要关注威胁情报里的CSS注入风险,但我搞不清具体该查什么。我们项目用了动态加载用户自定义样式的功能,会不会有隐患? 比如下面这段用户可能提交的CSS: .user-content... シ翼杨 安全 2026-03-31 15:23:12 1 回答 44 浏览 Taro 中如何正确使用 CSS Modules 避免样式污染? 我在 Taro 项目里尝试用 CSS Modules 写组件样式,但发现类名没被局部化,还是全局生效了,是不是配置有问题? 我的文件是 index.module.css,也按文档 import 了,但... 公孙一诺 框架 2026-03-21 18:38:17
先说怎么验证。你试过 url(javascript:alert(1)) 能弹窗,说明已经成功触发了——这就是典型的CSS表达式注入。浏览器解析到 background-image 或 content 属性里的 javascript: 协议时会执行,哪怕是在 data- 属性拼接进来的。你可以再试试这些 payload:
url('javascript:alert(document.domain)')或者通过其他支持 js 协议的属性比如 background、list-style-image 等绕过过滤。即使你过滤了 @import,攻击者根本不需要它,直接用 url() 配合 javascript: 就能完成 XSS。
至于修复,别想着靠转义或者字符串替换来堵漏,太容易被绕过。正确的做法是:
1. 绝对禁止用户控制完整的CSS样式字符串。如果你非要支持自定义样式,应该只允许用户选择预设的 class 名,而不是传一整段 style 字符串。
2. 如果必须接受样式输入,使用白名单机制限制可设置的属性(比如只允许 color、background-color),然后对值做严格校验,比如颜色必须是 hex/rgb 格式。
3. 在插入 DOM 前,用 CSSOM API 逐条解析和过滤,不要用 innerHTML 或 style.cssText 直接写入。
4. 加上 CSP 头,至少设置
style-src 'self',禁用内联样式和 javascript: 协议,这样即使有注入也执行不了。最根本的:别让用户的内容变成CSS代码,这是原则。你现在这逻辑相当于 eval(cssString),和 eval(jsString) 没区别,危险得很。
如果能触发弹窗,那基本可以确认漏洞存在了。因为
content属性支持URL格式,而浏览器会尝试加载这个URL,当遇到javascript:协议时就会执行代码。至于修复方案,常见的做法有两种:
1. **完全禁用动态CSS功能**:如果你觉得这个功能没啥必要,直接移除它是最简单有效的办法。
2. **使用白名单过滤并转义**:如果一定要保留这个功能,建议对用户输入的内容做严格的白名单校验,只允许特定的CSS属性值。同时,可以用正则把危险字符(比如括号、冒号等)替换掉,像这样:
不过说实话,这种过滤方式还是有点冒险,推荐直接用安全的替代方案,比如通过预定义的类名来控制样式,而不是让用户直接输入CSS。
最后提醒一下,千万别只依赖黑名单过滤,那样很容易漏掉某些奇怪的payload。