Vue模板中{{}}插值默认安全,v-html需用DOMPurify净化,v-bind属性自动转义但URL类属性须校验协议,富文本应服务端净化并配合CSP策略。

Vue 模板语法本身已内置多层转义防护,但安全不是“开了就完事”,关键在于理解哪些地方默认安全、哪些地方会主动绕过防护,以及如何补足缺口。
{{ }} 插值是默认最安全的入口
只要用双大括号渲染数据,Vue 就会自动把 、<code>>、&、"、' 转成对应 HTML 实体。比如:
-
userInput = '<script>alert(1)</script>' - 渲染
<div>{{ userInput }}</div>→ 页面显示纯文本<script>alert(1)</script>,不执行
这个转义靠的是浏览器原生 textContent,只要浏览器没严重漏洞,基本无风险。
v-html 是唯一明确放弃转义的出口
一旦使用 v-html,Vue 就完全信任你传入的内容,不做任何过滤。
-
v-html="userContent"中若含<img onerror="fetch('/api/steal')" alt="处理 Vue 模板语法的转义陷阱,如何保障数据安全?" >,就会触发执行 - 即使内容来自后端,也不能直接信——必须先净化再绑定
应对方式:
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 引入 DOMPurify 做前端二次过滤
import DOMPurify from 'dompurify' methods: { safeHtml(html) { return DOMPurify.sanitize(html, { ALLOWED_TAGS: ['p', 'br', 'strong', 'ul', 'li'], ALLOWED_ATTR: ['class'] }) } } - 模板中写成
v-html="safeHtml(userContent)" - 更稳妥的做法是服务端统一处理:接收时用
bleach(Python)或sanitize-html(Node.js)按白名单清洗,前端只负责渲染
动态 attribute 绑定也受保护,但有边界v-bind:title="userInput" 会自动转义,防止 " 提前闭合属性导致注入。
但注意:
-
v-bind:不处理事件绑定(如v-on:click),不能把用户输入直接当事件处理器 -
:href、:src等 URL 类属性需额外校验协议,避免javascript:alert()或data:text/html,类攻击 - 建议对 URL 字段做前端白名单检查(只允许
https?://、/、#开头)
富文本场景不能只靠前端
哪怕用了 DOMPurify,也要配合服务端策略:
- 存储优先用 Markdown,而非原始 HTML
- HTTP 响应头加上
Content-Security-Policy: script-src 'self'; object-src 'none' - 后端返回 HTML 前,强制走一次服务端净化
不复杂但容易忽略。
立即学习“前端免费学习笔记(深入)”;

















