uni-app中不存在vue 2风格的vue.filter机制,因此“过滤器被xss注入”前提不成立;真正风险在于v-html等场景未净化渲染,应统一在响应拦截器中调用dompurify白名单净化。

uni-app 里根本不存在 Vue 2 风格的 Vue.filter 过滤器机制,所以“过滤器被 XSS 注入”这个前提不成立——它压根不会执行用户输入的 JS,也不会动态编译模板字符串。真正危险的是你误以为用了“过滤器”就安全了,结果在 v-html 或 innerHTML 场景下直接渲染未净化的内容。
uni-app 中没有 Vue.filter,别被术语带偏
很多人搜“uni-app 过滤器 XSS”,其实是混淆了概念:filter 在 uni-app(尤其是 Vue 3 项目)中默认指向 CSS 的 filter 属性(比如 filter: grayscale(1)),和数据处理完全无关。Vue 2 的全局过滤器 API Vue.filter 已被 Vue 3 移除,uni-app 基于 Vue 3 构建,不支持该写法。你在 main.js 里写 Vue.filter('xss', ...) 不会生效,也起不到任何防护作用。
常见错误现象:
- 在
main.js中注册了Vue.filter('safeHtml', DOMPurify.sanitize),但在页面中用v-html="$options.filters.safeHtml(html)"却没效果 - 以为加了“过滤器”就等于防住了 XSS,结果上线后仍被
<img src="https://img.php.cn/?x-oss-process=image/resize,p_40" alt="uni-app中如何防止过滤器被恶意脚本XSS注入">攻破
真正该拦截 XSS 的位置:响应拦截器 + v-html 前净化
所有来自后端的富文本、用户评论、后台配置的 HTML 内容,必须在进入视图前做一次白名单净化。不要依赖组件内零散处理,统一收口到请求响应层最可靠。
实操建议:
- 在
uni.request的success回调或封装的请求工具函数中,对返回字段(如res.data.content)调用DOMPurify.sanitize() - 若使用
uni-app的uniCloud或 axios 封装,把净化逻辑放在响应拦截器里,例如:response => ({ ...response, data: xssSanitizePayload(response.data) }) - 避免在模板中写
v-html="rawHtml",改用v-html="DOMPurify.sanitize(rawHtml)"(需确保已引入并挂载到全局或组件) - 禁止将用户输入拼接到
eval、setTimeout、new Function等动态执行上下文中
DOMPurify 配置必须用白名单,禁用黑名单式过滤
简单正则替换 <script></script> 或 onerror 是无效的——攻击者用大小写混写、空格绕过、Unicode 编码就能轻松击穿。DOMPurify 的价值就在于它基于 HTML 解析器做语义级净化,不是字符串匹配。
关键配置项(必须显式设置):
-
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br', 'img']—— 只放业务真需要的标签 -
ALLOWED_ATTR: ['src', 'alt', 'title']—— 图片只允许这几个属性,onerror自动被剔除 -
ALLOWED_URI_REGEXP: /^https?:\/\//—— 强制外链只能是 http/https,干掉javascript:和data: - 务必启用
SAFE_FOR_TEMPLATES: true,避免净化后 HTML 被 Vue 模板引擎二次解析出问题
容易忽略的渲染陷阱:v-html 不是唯一入口
XSS 不只发生在 v-html。以下写法同样高危,且常被忽略:
-
<text>{{ userNickname }}</text>—— 如果昵称含<span onclick="..."></span>,uni-app 的{{}}默认只做文本插值,但某些平台(如 H5)在特定条件下可能触发解析 -
<view :style="'color:' + userColor"></view>—— 动态 style 绑定若未校验,可注入expression(...)(IE)或url(javascript:...) - 使用
uni.setStorageSync存储 HTML 字符串,后续再读取渲染 —— 存储本身不触发,但读取后若直接v-html就等于绕过所有前置净化
真正难防的从来不是 <script></script>,而是那些看起来“无害”的标签+事件组合。净化必须在数据落地前完成,而不是等它出现在模板里才想起来处理。











