如何防止Vue中通过URL参数引发的反射型XSS?

远香(打工版) 阅读 67

我最近在做一个搜索功能,URL里会带 keyword 参数,然后直接显示在页面上。但安全扫描说有反射型XSS风险,我试过用 v-html 但好像更危险了……

现在代码是这样的:

<template>
  <div>
    您搜索的是:{{ $route.query.keyword }}
  </div>
</template>

这样写真的会被XSS攻击吗?如果用户传了个 <script> 标签进来会执行吗?该怎么安全地展示这个参数?

我来解答 赞 11 收藏
二维码
手机扫码查看
2 条解答
设计师国凤
官方文档里说,直接使用双大括号插值 {{ }} 在Vue中会自动对数据进行转义,防止XSS攻击。不过,如果你不小心使用了 v-html 来渲染用户输入的内容,那就会非常危险,因为这会导致浏览器直接解析并执行其中的HTML和脚本。

在你的情况中,直接使用 {{ $route.query.keyword }} 是安全的,因为Vue默认会转义插值中的特殊字符。但是为了保险起见,并且遵循最佳实践,你可以手动对 URL 参数进行转义,确保安全。可以使用 JavaScript 的 encodeURIComponent 或者一些安全库来处理。

这里有一个简单的例子,展示如何手动转义:

computed: {
safeKeyword() {
return encodeURIComponent(this.$route.query.keyword);
}
}


然后在模板中使用这个计算属性:

<template>
<div>
您搜索的是:{{ safeKeyword }}
</div>
</template>


不过请注意,encodeURIComponent 对于 HTML 转义来说可能不够全面,它主要用于编码 URI 组件,而不是 HTML 实体。所以对于 HTML 内容的安全输出,通常建议使用专门的安全库来进行转义。
点赞
2026-03-23 10:06
公孙梓晴
先说结论:你现在这样写 {{ $route.query.keyword }} 其实反而是安全的。

Vue的模板插值默认会对HTML进行转义,用户传 进来,页面上会直接显示这串文本,不会被执行。所以你完全没必要用 v-html,用了 v-html 才真的完蛋。

但为什么扫描器还报反射型XSS?这里有个点要注意:Vue的转义是针对模板渲染阶段的,如果你后面通过某些方式(比如某个第三方组件、或者你自己用了 innerHTML)绕过了Vue的转义,那就有问题了。

更稳妥的做法是自己在显示前先转义一遍,别全靠框架:

// 简单的转义函数
function escapeHtml(str) {
const div = document.createElement('div')
div.textContent = str
return div.innerHTML
}


然后模板里这样用:

<template>
<div>
您搜索的是:{{ escapeHtml($route.query.keyword) }}
</div>
</template>

<script>
export default {
methods: {
escapeHtml(str) {
const div = document.createElement('div')
div.textContent = str
return div.innerHTML
}
}
}
</script>


另外,keyword 从 URL 取出来默认是字符串,如果你之前对它做过 decodeURIComponent 或者其他处理,也要确保处理顺序是对的,先转义再拼接。

还有就是可以在服务端加 CSP 响应头,多重防护嘛。
点赞 1
2026-03-13 11:05