CSS样式中的expression()如何绕过事件属性过滤导致XSS? 打工人尚勤 提问于 2026-02-12 21:11:25 阅读 57 安全 我在开发评论系统时发现,即使过滤了所有on开头的事件属性,用户提交的CSS代码还是能触发XSS。比如有人写了个这样的样式: div { width: expression(alert('XSS')); } 测试时发现这段代码在兼容模式下会弹出窗口。之前都是直接过滤onerror/onload等属性,但expression()这种CSS表达式完全没考虑到。现在该怎么修改过滤规则才能同时拦截事件属性和这种危险的CSS特性呢? XSS防护输入过滤 我来解答 赞 8 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 程序员朝炜 Lv1 这个问题确实挺棘手的,我之前也碰到过类似的场景。expression() 是 IE 时代的一个老旧特性,虽然现代浏览器基本都废弃了它,但如果你的系统需要兼容旧版 IE,那就得特别小心。 要解决这个问题,我的建议是直接禁用 expression 这个关键字。你可以在过滤规则里加上对它的检测,比如在处理用户提交的 CSS 时,检查是否存在类似 expression 的字符串。如果发现就直接拒绝保存或者移除相关代码。 具体实现的话,可以写一个正则表达式来匹配 expression 和它的内容。比如这样: function sanitizeCss(css) { // 匹配 expression(...) 并移除 return css.replace(/expressions*(.*?)/gi, ''); } 这个函数会找到所有形如 expression(...) 的内容并把它清空。不过要注意,正则表达式虽然能解决大部分情况,但它不是万能的。如果你的系统允许更复杂的 CSS 输入,最好还是结合专门的 CSS 解析库来做进一步的安全处理。 另外,我还建议你在服务端和客户端同时做校验。服务端用来拦截恶意输入,客户端用来实时提醒用户哪些内容不被允许。双重保险总归更靠谱一些。 最后再说一句,其实最好的办法是完全禁止用户提交自定义 CSS。如果你的需求允许,可以改成让用户选择预定义的样式模板,这样既安全又省心。毕竟,开放 CSS 输入的风险实在太大了,防不胜防啊! 回复 点赞 4 2026-02-18 16:17 极客慧利 Lv1 expression() 是 IE 特有的 CSS 表达式功能,能在样式里执行 JS,确实是个经典的 XSS 向量。你只过滤 on 开头的事件属性是不够的,因为这玩意根本不在 HTML 属性里触发,而是藏在 CSS 里面。 要彻底堵住,得从两头下手:一是输入时过滤或移除 expression,二是避免使用不安全的内联样式处理。 最直接的办法是在过滤 CSS 时正则干掉 expression(不区分大小写): cssText = cssText.replace(/expressions*([^)]*)/gi, ''); 但注意别漏了换行或空格绕过的情况,比如 expre ssion(alert()) 这种拆分写法。建议先压缩空白再匹配: cssText = cssText.replace(/s+/g, ' ').replace(/expressions*(.*?)/gi, ''); 更稳一点的做法是直接禁止用户提交完整 CSS,改用白名单字段控制样式,比如只允许 { color: #xxx } 这种基础属性。 另外别忘了 -moz-binding、behavior:url() 这些也能触发 XSS,一并过滤掉。 最后建议把 user-content 的 style 标签全干掉,或者用 CSP 做兜底,style-src 'unsafe-inline' 能不用就别用。这波优化一下,基本就能封死了。 回复 点赞 6 2026-02-12 21:12 加载更多 相关推荐 1 回答 33 浏览 前端输入验证只靠CSS能防XSS吗? 我在做一个评论功能,用户输入内容后直接显示在页面上。听说要防止XSS攻击,但我看有些项目只用了CSS的white-space: pre-wrap和overflow-wrap: break-word来处... Mr.梦玲 前端 2026-03-21 09:41:19 1 回答 64 浏览 白盒测试时如何判断CSS会不会引发安全问题? 最近在做Web安全的白盒测试,看到项目里有一段动态生成的CSS,担心会不会有XSS风险。虽然CSS本身不能执行JS,但听说某些属性比如url()或者@import可能被利用,是不是真的? 比如下面这段... Mc.莉娜 安全 2026-03-19 05:24:22 2 回答 56 浏览 前端安全审计时怎么判断CSS有没有安全风险? 最近在做项目的安全审计,听说CSS也可能有安全问题,比如XSS之类的。但我一直以为CSS是静态样式,不会执行代码,所以有点懵。 我试过用一些在线工具扫描,但没报错。不过我们有个动态加载用户自定义主题的... UE丶思源 前端 2026-03-03 20:06:21 2 回答 52 浏览 设置了X-XSS-Protection后CSS样式被过滤导致页面错乱怎么办? 我在开发页面时启用了X-XSS-Protection: 1; mode=block头,但发现动态生成的用户提交内容里的CSS样式被过滤了。比如用户输入的标签带内联样式时,浏览器直接移除了style属性... 程序员亚美 安全 2026-01-29 16:50:32 1 回答 44 浏览 Taro 中如何正确使用 CSS Modules 避免样式污染? 我在 Taro 项目里尝试用 CSS Modules 写组件样式,但发现类名没被局部化,还是全局生效了,是不是配置有问题? 我的文件是 index.module.css,也按文档 import 了,但... 公孙一诺 框架 2026-03-21 18:38:17 2 回答 57 浏览 Taro页面跳转后样式被重置,如何保持原页面CSS? 在Taro项目里用了navigator标签跳转页面,发现目标页面的CSS样式全被重置了。比如这个按钮样式: .button { background: linear-gradient(to right... 轩辕文茹 框架 2026-02-06 16:52:33 1 回答 74 浏览 Material-UI按钮样式覆盖不了自定义的CSS如何解决? 我在用Vue和Material-UI做按钮组件时遇到问题,想给按钮加个悬停效果,但自定义的CSS样式完全没生效... 代码是这样的: 点击我 .custom-btn { background: #4C... IT人凡敬 组件 2026-01-28 11:07:26 1 回答 30 浏览 Taro 中使用 CSS Modules 为啥样式没生效? 我在 Taro 项目里尝试用 CSS Modules 写组件样式,但发现类名没被编译成哈希值,样式也没应用上。我明明把文件命名为 index.module.css 了啊。 这是我的样式代码: .con... 司空梓童 框架 2026-03-29 23:12:14 1 回答 36 浏览 Next.js中全局CSS在SSR时为什么样式错乱? 我在Next.js项目里引入了一个全局的CSS文件,本地开发看着没问题,但一部署到服务器做SSR渲染,页面样式就乱了,有些类名没生效,顺序也不对。 我试过把CSS放在pages/_app.js里用im... 小静静 框架 2026-03-29 19:47:14 1 回答 25 浏览 Taro 中使用 CSS 自定义属性在小程序端不生效怎么办? 我在 Taro 项目里用 CSS 变量做主题色配置,H5 跑得好好的,但一到微信小程序真机上就失效了,样式直接没了。查了文档说小程序不支持 CSS 自定义属性,但有没有什么兼容方案啊? 我试过把变量写... 开发者钰莹 框架 2026-03-26 17:37:25
expression()是 IE 时代的一个老旧特性,虽然现代浏览器基本都废弃了它,但如果你的系统需要兼容旧版 IE,那就得特别小心。要解决这个问题,我的建议是直接禁用
expression这个关键字。你可以在过滤规则里加上对它的检测,比如在处理用户提交的 CSS 时,检查是否存在类似expression的字符串。如果发现就直接拒绝保存或者移除相关代码。具体实现的话,可以写一个正则表达式来匹配
expression和它的内容。比如这样:这个函数会找到所有形如
expression(...)的内容并把它清空。不过要注意,正则表达式虽然能解决大部分情况,但它不是万能的。如果你的系统允许更复杂的 CSS 输入,最好还是结合专门的 CSS 解析库来做进一步的安全处理。另外,我还建议你在服务端和客户端同时做校验。服务端用来拦截恶意输入,客户端用来实时提醒用户哪些内容不被允许。双重保险总归更靠谱一些。
最后再说一句,其实最好的办法是完全禁止用户提交自定义 CSS。如果你的需求允许,可以改成让用户选择预定义的样式模板,这样既安全又省心。毕竟,开放 CSS 输入的风险实在太大了,防不胜防啊!
要彻底堵住,得从两头下手:一是输入时过滤或移除 expression,二是避免使用不安全的内联样式处理。
最直接的办法是在过滤 CSS 时正则干掉 expression(不区分大小写):
但注意别漏了换行或空格绕过的情况,比如 expre ssion(alert()) 这种拆分写法。建议先压缩空白再匹配:
更稳一点的做法是直接禁止用户提交完整 CSS,改用白名单字段控制样式,比如只允许 { color: #xxx } 这种基础属性。
另外别忘了 -moz-binding、behavior:url() 这些也能触发 XSS,一并过滤掉。
最后建议把 user-content 的 style 标签全干掉,或者用 CSP 做兜底,style-src 'unsafe-inline' 能不用就别用。这波优化一下,基本就能封死了。