首页 > 其他分享 >第三十九篇 vue - 最佳实践 - 安全

第三十九篇 vue - 最佳实践 - 安全

时间:2023-04-04 23:55:56浏览次数:37  
标签:Vue vue 第三十九 用户 最佳 HTML 渲染 JavaScript 模板

报告漏洞

虽然很少发现新的漏洞,但我们仍建议始终使用最新版本的 Vue 及其官方配套库,以确保你的应用尽可能地安全。

首要规则:不要使用无法信赖的模板

使用 Vue 时最基本的安全规则就是不要将无法信赖的内容作为你的组件模板。使用无法信赖的模板相当于允许任意的 JavaScript 在你的应用中执行。更糟糕的是,如果在服务端渲染时执行了这些代码,可能会导致服务器被攻击。
Vue.createApp({
  template: `<div>` + userProvidedString + `</div>` // 永远不要这样做!
}).mount('#app')

Vue 模板会被编译成 JavaScript,而模板内的表达式将作为渲染过程的一部分被执行。尽管这些表达式在特定的渲染环境中执行,但由于全局执行环境的复杂性,Vue 作为一个开发框架,要在性能开销合理的前提下完全避免潜在的恶意代码执行是不现实的。避免这类问题最直接的方法是确保你的 Vue 模板始终是可信的,并且完全由你控制

Vue 自身的安全机制

HTML 内容
无论是使用模板还是渲染函数,内容都是自动转义的。这意味着在这个模板中:

<h1>{{ userProvidedString }}</h1>

如果 userProvidedString 包含了:

'<script>alert("hi")</script>'

那么它将被转义为如下的 HTML:

&lt;script&gt;alert(&quot;hi&quot;)&lt;/script&gt;

从而防止脚本注入。这种转义是使用 textContent 这样的浏览器原生 API 完成的,所以只有当浏览器本身存在漏洞时,才会存在漏洞。
Attribute 绑定
同样地,动态 attribute 的绑定也会被自动转义。这意味着在这个模板中:

<h1 :title="userProvidedString">
  hello
</h1>

如果 userProvidedString 包含了:

'" onclick="alert(\'hi\')'

那么它将被转义为如下的 HTML:

&quot; onclick=&quot;alert('hi')

从而防止在 title attribute 解析时,注入任意的 HTML。这种转义是使用 setAttribute 这样的浏览器原生 API 完成的,所以只有当浏览器本身存在漏洞时,才会存在漏洞。

潜在的危险

在任何 Web 应用中,允许以 HTML、CSS 或 JavaScript 形式执行未经无害化处理的、用户提供的内容都有潜在的安全隐患,因此应尽可能避免。不过有时候一些风险或许是可以接受的。

例如,像 CodePen 和 JSFiddle 这样的服务允许执行用户提供的内容,但这是在 iframe 这样一个可预期的沙盒环境中。当一个重要的功能本身会伴随某种程度的漏洞时,就需要你自行权衡该功能的重要性和该漏洞所带来的最坏情况
注入 HTML
我们现在已经知道 Vue 会自动转义 HTML 内容,防止你意外地将可执行的 HTML 注入到你的应用中。然而,在你知道 HTML 安全的情况下,你还是可以显式地渲染 HTML 内容
1、使用模板:

<div v-html="userProvidedHtml"></div>

2、使用渲染函数:

h('div', {
  innerHTML: this.userProvidedHtml
})

3、以 JSX 形式使用渲染函数:

<div innerHTML={this.userProvidedHtml}></div>


警告

用户提供的 HTML 永远不能被认为是 100% 安全的,除非它在 iframe 这样的沙盒环境中,或者该 HTML 只会被该用户看到。此外,允许用户编写自己的 Vue 模板也会带来类似的危险。
URL 注入
在这样一个使用 URL 的场景中:

<a :href="userProvidedUrl">
  click me
</a>

如果这个 URL 允许通过 javascript: 执行 JavaScript,即没有进行无害化处理,那么就会有一些潜在的安全问题。可以使用一些库来解决此类问题,比如 sanitize-url,但请注意:如果你发现你需要在前端做 URL 无害化处理,那你的应用已经存在一个更严重的安全问题了。任何用户提供的 URL 在被保存到数据库之前在应该先在后端做无害化处理。这样,连接到你 API 的每一个客户端都可以避免这个问题,包括原生移动应用。另外,即使是经过无害化处理的 URL,Vue 也不能保证它们指向安全的目的地
样式注入
<a
  :href="sanitizedUrl"
  :style="userProvidedStyles"
>
  click me
</a>

我们假设 sanitizedUrl 已进行无害化处理,它是一个正常 URL 而非 JavaScript。然而,由于 userProvidedStyles 的存在,恶意用户仍然能利用 CSS 进行“点击劫持”,例如,可以在“登录”按钮上方覆盖一个透明的链接。如果用户控制的页面 https://user-controlled-website.com/ 专门仿造了你应用的登录页,那么他们就有可能捕获用户的真实登录信息。

你可以想象,如果允许在 <style> 元素中插入用户提供的内容,会造成更大的漏洞,因为这使得用户能控制整个页面的样式。因此 Vue 阻止了在模板中像这样渲染 style 标签:

<style>{{ userProvidedStyles }}</style>

为了避免用户的点击被劫持,我们建议仅在沙盒环境的 iframe 中允许用户控制 CSS。或者,当用户控制样式绑定时,我们建议使用其对象值形式并仅允许用户提供能够安全控制的、特定的属性,就像这样:

<a
  :href="sanitizedUrl"
  :style="{
    color: userProvidedColor,
    background: userProvidedBackground
  }"
>
  click me
</a>
JavaScript 注入
我们强烈建议任何时候都不要在 Vue 中渲染 <script>,因为模板和渲染函数不应有其他副作用。但是,渲染 <script> 并不是插入在运行时执行的 JavaScript 字符串的唯一方法。

每个 HTML 元素都有能接受字符串形式 JavaScript 的 attribute,例如 onclick、onfocus 和 onm ouseenter。绑定任何用户提供的 JavaScript 给这些事件 attribute 都具有潜在风险,因此需要避免这么做。

警告

用户提供的 JavaScript 永远不能被认为是 100% 安全的,除非它在 iframe 这样的沙盒环境中,或者该段代码只会在该用户登陆的页面上被执行
有时我们会收到漏洞报告,说在 Vue 模板中可以进行跨站脚本攻击 (XSS)。一般来说,我们不认为这种情况是真正的漏洞,因为没有切实可行的方法,能够在以下两种场景中保护开发者不受 XSS 的影响。

  1、开发者显式地将用户提供的、未经无害化处理的内容作为 Vue 模板渲染。这本身就是不安全的,Vue 也无从溯源。

  2、开发者将 Vue 挂载到可能包含服务端渲染或用户提供内容的 HTML 页面上,这与 #1 的问题基本相同,但有时开发者可能会不知不觉地这样做。攻击者提供的 HTML 可能在普通 HTML 中是安全的,但在 Vue 模板中是不安全的,这就会导致漏洞。最佳实践是:不要将 Vue 挂载到可能包含服务端渲染或用户提供内容的 DOM 节点上。

最佳实践

最基本的规则就是只要你允许执行未经无害化处理的、用户提供的内容 (无论是 HTML、JavaScript 还是 CSS),你就可能面临攻击。无论是使用 Vue、其他框架,或是不使用框架,道理都是一样的。

除了上面为处理潜在危险提供的建议,我们也建议你熟读下面这些资源:

  1、HTML5 安全手册
  2、OWASP 的跨站脚本攻击 (XSS) 防护手册
  
接着你可以利用学到的知识,来审查依赖项的源代码,看看是否有潜在的危险,防止它们中的任何一个以第三方组件或其他方式影响 DOM 渲染的内容。

后端协调

类似跨站请求伪造 (CSRF/XSRF) 和跨站脚本引入 (XSSI) 这样的 HTTP 安全漏洞,主要由后端负责处理,因此不是 Vue 职责范围内的问题。但是,你应该与后端团队保持沟通,了解如何更好地与后端 API 进行交互,例如在提交表单时附带 CSRF 令牌

服务端渲染 (SSR)

在使用 SSR 时还有一些其他的安全注意事项,因此请确保遵循我们的 SSR 文档给出的最佳实践来避免产生漏洞

标签:Vue,vue,第三十九,用户,最佳,HTML,渲染,JavaScript,模板
From: https://www.cnblogs.com/caix-1987/p/17288312.html

相关文章

  • vue数组和对象进行 watch 和 watchEffect 对比
    constarr1=ref([]);constarr2=reactive([]);constobj1=ref({});constobj2=reactive({});watchEffect(()=>{console.log("watchEffectarr1",arr1.value);console.log("watchEffectarr2",arr2)......
  • 超详细!新手如何创建一个Vue项目
    目录一、在官网下载Vue.js二、使用<script>标签直接引入本地的vue.js三、使用CDN引入Vue.js四、验证是否安装成功五、安装VueDevtools浏览器调试插件不同浏览器导入方法本篇仅以HBuilderX为例,其余开发软件同样适用这里两种方法,使用<script>标签直接引入本地的vue.js或使用CDN......
  • 如何在vue3获取 DOM 元素
    获取dom的ref元素名称,要对应暴露的名称,不然会出现无效的dom报错,也就是拿到的是null在setup中,使用ref(null)获取dom不能直接在setup里面拿到dom的值,因为setup对应的生命周期是created,所以必须在后续的生命周期钩子里面拿到,比如onMounted注意:ref不要加冒号,直接写dom元素名称......
  • vue引入粒子背景图效果
    安装依赖npminstallvue-particles--save-devmain.jsimportVueParticlesfrom'vue-particles'Vue.use(VueParticles)template  <vue-particles     color="#409EFF"     :particleOpacity="0.7"     :parti......
  • Vue3——使用deep进行样式穿透的时候发出v-deep警告
    前言其实只是一个警告,如果你不在意也是可以的,不过有点强迫症就按着提示说的改了,然后又去官网看了下对应的文档;!>::v-deepusageasacombinatorhasbeendeprecated.Use:deep()instead.这里没啥好说的,因为Vue3的文档中有对应的解释组件作用域CSS了,而且就算不看文档根据提......
  • DayOne-Vue的基本使用指令以及过滤器
    一、Vue1、什么是VueVue是一个流行的JavaScript框架,用于构建用户界面。它被设计成渐进式的,可以逐步应用到现有的项目中,也可以构建全新的应用。Vue的核心库只关注视图层,因此易于集成到其他库或现有项目中。Vue具有响应式和组件化的特性,使得开发者可以更轻松地管理和维护复杂的用......
  • 使用jenkins一键打包发布vue项目
    jenkins的安装Jenkins是一款开源CI&CD软件,用于自动化各种任务,包括构建、测试和部署软件。Jenkins支持各种运行方式,可通过系统包、Docker或者通过一个独立的Java程序。安装这里的操作系统为WSLUbuntu,其它系统的安装的请参考jenkins官方文档wget-q-O-https://pkg.jenkins.......
  • vue 之 computed方法自带缓存踩坑1
    使用场景:ant-vue穿梭框使用页面使用computed方法处理组织结构数据,退出页面时,对加载数据做了setnull操作,再次进入页面时,穿梭框只显示数据,无法做左右穿梭功能。原因:computed方法在页面初始化时执行,且只执行一次,并会将方法内的数据进行缓存。退出页面做了数据清除工作,但并为清楚......
  • 项目实践后的图片压缩完整使用过程【vue3+js】
    van-uploader+图片压缩+图片base64转成file compressImage.jsconstACCEPT=['image/jpg','image/png','image/jpeg']constMAXSIZE=1024*1024*2;constMAXTIP="4"//压缩算法函数/*1.首先拿到了base64的图片字符串2.创建一个image对象,获......
  • VUE watch监听器的基本使用方法详解
    1、下面代码是watch的一种简单的用法<divid="app"><inputtype="text"v-model="firstName"/></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>......