精读 Vue 官方文档系列 🎉
报告安全漏洞
如发现任何安全漏洞,请邮件给 security@vuejs.org。会有全职贡献者及时处理。
推荐始终使用最新版本的 Vue 及其官方的周边库,以确保应用尽可能安全。
永远不要使用不可信任的模板
永远不要将不可信任的内容作为模板内容使用,最典型的就是用户提供的内容,包括 HTML、JS、CSS。
HTML 注入
最典型的 XSS 攻击:
new Vue({
el: '#app',
template: `<div>` + userProvidedString + `</div>` // 永远不要这样做
})
Vue 内部会通过浏览器原生的
textContent进行转义。 如果你完全能确保动态渲染的内容绝对正确,你也可以通过以下方式显示的渲染 HTML 内容:
- 使用模板:
<div v-html="userProvidedHtml"></div>
- 使用渲染函数:
h('div', {
domProps: {
innerHTML: this.userProvidedHtml
}
})
- 使用基于 JSX 的渲染函数:
<div domPropsInnerHTML={this.userProvidedHtml}></div>
Attribute 注入
通过闭合 Attribute 间接注入新的 Attribute 来实现攻击
var dynamicTitle = '" onclick="alert(\'hi\')';
var h1 = '<h1 title="'+ dynamicTitle +'">hello</h1>';
为了确保不会产生出此种攻击,我们应该总是基于 Vue 提供的 v-bind 指令来绑定 Attribute 并传值。
<h1 v-bind:title="userProvidedString">
hello
</h1>
如果 userProvidedString 包含攻击代码,它会被转义为:
" onclick="alert('hi')
该转义通过诸如 setAttribute 的浏览器原生的 API 完成,所以除非浏览器本身存在安全漏洞,否则不会存在安全漏洞。
将不安全的内容赋值给 onclick、onfocus、onmouseenter 等事件句柄
开发者应当时长保持风险意思,不要绕开 Vue 本身功能去操作模板。
URL 注入
主要是利用 href 属性可以执行 javascript:alert(\'hi\') 表达式的特性。
<a v-bind:href="userProvidedUrl">
click me
</a>
最优的解决方案,是后端入库时就对 URL 进行过滤。
CSS 注入
<a
v-bind:href="sanitizedUrl"
v-bind:style="userProvidedStyles"
>
click me
</a>
如果上例的 a 标签允许接收用户提供的不能 100% 保证安全的链接与样式,可以想象的到,攻击者会改变当前标签的展现样式。比如将其透明化并定位到登录按钮的上面,然后用户点击登录时,跳转到一个类似的钓鱼网站,从而窃取用户信息,进行“钓鱼攻击”。
解决方案就是不要给标签的
style属性直接赋值,而是总是通过对象语法为特定的 CSS 属性赋值。
<a
v-bind:href="sanitizedUrl"
v-bind:style="{
color: userProvidedColor,
background: userProvidedBackground
}"
>
click me
</a>
通过沙箱来运行不安全的HTML、CSS、JS内容。
借鉴 CodePen 与 JSFiddle 可以将不能确定是否安全的内容放置在一个 iframe 中以沙箱的方式来运行内容。
最佳实践
请详细阅读一下文章,它们详细的记录了各种攻击方法,从中吸取经验,加强我们应用的安全性: