vue2.x学习笔记(三十一)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12683075.html。
安全
现在的企业都比较在意信息系统的安全问题,在使用vue的过程中也要注意这一点。
报告安全漏洞
官方承诺,当收到一个安全漏洞报告,将给予其最高优先级,并由全职贡献者停下手中的工作处理此事(可以将发现的安全漏洞通过邮件给security@vuejs.org的形式反馈给官方)。虽然发现新安全漏洞是比较罕见的事情,但是官方仍然是推荐始终使用最新版本的vue及其官方的周边库,以确保应用尽可能安全。
安全的第一原则:用于不要使用不可信任的模板
在使用vue的时候最基本的安全规则是永远不要将不可信任的内容作为模板内容使用,因为这样做等价于允许在应用程序中执行任意的javascript一样,前端逻辑可能会因此被恶意破坏。甚至更糟糕的是如果在服务器渲染的话可能导致服务器被攻破。
new Vue({
el: '#app',
template: `<div>` + userProvidedString + `</div>` // 永远不要这样做
})
因为vue的模板是最终被编译称为javascript的,而其中的表达式会作为渲染流程的一部分执行。尽管该表达式是在一个特定的渲染上下文中进行运算的。考虑到潜在的全局运行环境的复杂性,作为类似vue的框架,想要完全让代码远离潜在的恶意代码行而不导致性能问题,是不切实际的。最直接的回避这类问题的方法,就是确保vue模板的内容始终是可信的,且是完全由你掌控的。
vue中的安全措施-html内容
不论使用模板还是渲染函数,内容都会被自动转义。也就是说,对于以下这份模板:
<h1>{{ userProvidedString }}</h1>
如果userProvidedString包含了:
'<script>alert("hi")</script>'
它就会被转义为以下的html:
<script>alert("hi")</script>
这样就在一定程度上避免了脚本注入,因为浏览器最终识别的内容不再是脚本,而是普通的文本。该转义是通过诸如textContent的浏览器原生api完成的,除非浏览器本身存在安全漏洞,否则是不会存在安全漏洞的。
vue中的安全措施-attribute绑定
同样的,动态的attribute绑定也会被自动转义。也就是说,对于以下这份模板:
<h1 v-bind:title="userProvidedString">
hello
</h1>
如果在userProvidedString中包含了:
'" onclick="alert(\'hi\')'
其就会被自动转义为以下的html:
" onclick="alert('hi')
这样就有效避免了通过闭合title属性而注入新的任意html。该转义是通过诸如textContent的浏览器原生api完成的,除非浏览器本身存在安全漏洞,否则是不会存在安全漏洞的。
潜在危险
在任何的web应用中,允许未过滤的用户提供的内容称为html、css或javascript都有潜在的危险,因此应当尽可能避免。尽管如此,有些情况下的风险是可接受的。
例如,类似Code和JSFiddle这样的服务就允许用户提供的内容直接被执行。但这是预期行为,且在iframe中以某种程度被隔离在沙箱中。当一些重要功能不可避免地依赖引入一些安全漏洞的时候,你的开发团队就需要自行在该功能的重要性和漏洞带来的最坏场景之间进行权衡。
注入html
如上面说到的,vue会自动转义html的内容,以此来避免向应用意外注入可执行的html。然而在一些场景中,你可能会很清楚这些html是安全的,这时你就可以显式地渲染html内容。
1.使用模板(v-html):
<div v-html="userProvidedHtml"></div>
2.使用渲染函数(render):
h('div', {
domProps: {
innerHTML: this.userProvidedHtml
}
})
3.使用基于jsx的渲染函数:
<div domPropsInnerHTML={this.userProvidedHtml}></div>
注意,永远不要认为用户提供的html是100%安全的,除非它是在一个iframe沙盒里或者应用中只有编写这些html的用户可以接触到它。除此之外,允许用户撰写其自己的vue模板会带来类似的危险。
注入url
在类似这样的url中:
<a v-bind:href="userProvidedUrl">
click me
</a>
如果没有对该url进行过滤以防止通过【javascript:】来执行javascript,则会有潜在的安全问题。有一些库,比如sanitize-url可以帮助你做这件事,但是请注意:只要你只是在前端进行了url过滤,那么就已经有了安全问题了。用户提供的url永远需要通过后端在入库之前进行过滤,然后这个问题就会在每个客户端连接该api的时候被阻止,包括原生的移动应用。此外还要注意,甚至对于被过滤的url,vue仍然无法帮助开发者保证它们会跳转到安全的目的地。
注入样式
来看这个示例:
<a
v-bind:href="sanitizedUrl"
v-bind:style="userProvidedStyles">
click me
</a>
我们先假设sanitizedUrl已经被过滤过了,所以这已经是一个完全真实的url且没有javascript。但通过userProvidedStyles,恶意用户仍然可以提供css来进行【点击诈骗】,例如将链接的样式设置为一个透明的方框覆盖在登录按钮之上,然后再把登录的地址做成你的应用的登录页的样子(假冒),它们就可能获取一个用户真实的登录信息(账号密码等)。
你可以想象到,允许一个用户为一个<style>元素提供内容,将产生甚至更严重的安全漏洞,比如上面的例子就可能会导致网站用户隐私信息被泄露的严重问题。这也是为什么vue在模板内避免渲染style标签的原因,例如:
<style>{{ userProvidedStyles }}</style>
为了确保用户完全远离【点击诈骗】,官方文档推荐只允许在一个iframe沙盒内进行css的完全控制。或让用户通过一个样式绑定来控制,我们推荐使用其对象语法且只允许用户提供特定的、可以安全控制的property的值,例如:
<a
v-bind:href="sanitizedUrl"
v-bind:style="{
color: userProvidedColor,
background: userProvidedBackground
}">
click me
</a>
这样,不符合css属性格式的值将会被直接抛弃,很大程度上避免了css注入的问题。
注入javascript
官方强烈不推荐使用vue渲染<script>元素,因为模板和渲染函数永远不应该产生副作用。然而,这并不是唯一包含可能在运行时会被视为javascript的字符串。
每个html元素都有接受javascript字符串作为其值的attribute,如onclick、onfocus和onmouseenter。将用户提供的javascript绑定到它们任意当中都是一个潜在的安全风险,因此应该避免。
请注意,永远不要认为用户提供的javascript是100%安全的,除非它是在一个iframe沙盒里或者应用中只有编写该javascript的用户可以接触到它。
有的时候我们会收到在vue模板中可以产生跨站脚本攻击(XSS)的安全漏洞报告。一般情况下,我们不会将这样的案例视为真正的安全漏洞,因为从以下两个可能允许CSS的场景来看,不存在可行的办法来保护开发者:
1.开发者显式地要求vue将用户提供地、未经过过滤的内容作为vue模板进行渲染。这是无法避免的不安全,因为vue没有办法知道其源头。
2.开发者向vue挂载包含服务端渲染或用户提供的内容的html的整个页面。这实际上和问题1是相同的,但是有的时候开发者可能没有意识到。这会使得攻击者提供作为普通html安全但对于vue模板不安全的html以导致安全漏洞。最佳实践是永远不要向vue挂载可能包含服务端渲染或用户提供的内容。
最佳实践
通用的规则是只要允许执行未过滤的用户提供的内容(不论作为html,javascript甚至css),你就可能令自己出于被攻击的境地。这些建议实际上不论使用vue还是别的框架,甚至不使用框架,都是成立的。
除了上述关于潜在危险的建议,官方文档还推荐自行熟悉以下资料:
然后利用学到的知识,对那些包含了第三方组件或通过其他方式影响渲染到dom的内容的依赖的源代码进行重新审查,以发现潜在的危险模式。
后端协作
http安全漏洞,诸如伪造跨站请求(CSRF/XSRF)和跨站脚本注入(XSSI),都是后端重点关注的方向,因此并不是vue所担心的。尽管如此,和后端团队交流学习任何和他们的api最好地进行交互,例如在表单提交的时候提交CSRF token,永远是一件好事。
服务端渲染(SSR)
使用SSR时存在额外的安全考量,因此需要开发者确认遵循官方的 SSR 文档中概括出的最佳实践,以避免安全漏洞的产生。
"我还是很喜欢你,像春风守护着晨曦,不曾远去。"
vue2.x学习笔记(三十一)的更多相关文章
- angular学习笔记(三十一)-$location(2)
之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...
- angular学习笔记(三十一)-$location(1)
本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...
- Java学习笔记三十一:Java 包(package)
Java 包(package) 一:包的作用: 如果我们在使用eclipse等工具创建Java工程的时候,经常会创建包,那么,这个包是什么呢. 为了更好地组织类,Java 提供了包机制,用于区别类名的 ...
- vue2.x学习笔记(十一)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12586416.html. 表单的输入绑定 表单的输入绑定是一块很重要的内容,因为所有的业务系统都离不开基础表单的录 ...
- PHP学习笔记三十一【const】
<?php //常量都是public类型 // const 常量名=赋值 .变量名不需要加$符号,也不需要要访问修饰符,默认就是public class A{ const TAX_RATE=0. ...
- VSTO 学习笔记(十一)开发Excel 2010 64位自定义公式
原文:VSTO 学习笔记(十一)开发Excel 2010 64位自定义公式 Excel包含很多公式,如数学.日期.文本.逻辑等公式,非常方便,可以灵活快捷的对数据进行处理,达到我们想要的效果.Exce ...
- python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法
python3.4学习笔记(二十一) python实现指定字符串补全空格.前面填充0的方法 Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0.zfill()方法语法:s ...
- kvm虚拟化学习笔记(三)之windows kvm虚拟机安装
KVM虚拟化学习笔记系列文章列表----------------------------------------kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51 ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
随机推荐
- 最大子矩阵hdu1559(二维前缀和)
最大子矩阵hdu1559 Problem Description 给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大. Input 输入数据的第一行为一个正整数T,表示有 ...
- Java并发基础01. 传统线程技术中创建线程的两种方式
传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...
- 在docker中部署redis主从配置
环境说明: 阿里云服务器 Ubuntu 16.04 docker 1.拉取Redis镜像 docker pull redis 2.配置Redis启动配置文件,此处我创建一个专用目录,存放Redis相关 ...
- 原来rollup这么简单之插件篇
大家好,我是小雨小雨,致力于分享有趣的.实用的技术文章. 内容分为翻译和原创,如果有问题,欢迎随时评论或私信,希望和大家一起进步. 大家的支持是我创作的动力. 计划 rollup系列打算一章一章的放出 ...
- 数据科学 R语言速成
文章更新于:2020-03-07 按照惯例,需要的文件附上链接放在文首: 文件名:R-3.6.2-win.exe 文件大小:82.4M 下载链接:https://www.lanzous.com/i9c ...
- python 天天生鲜项目
python 天天生鲜项目 django版:https://github.com/Ivy-1996/fresh flask版:https://github.com/Ivy-1996/flask-fre ...
- wireshark抓包实战(六),过滤器
目录 一.抓包过滤器 1.语法来源 2.语法 二.显示过滤器 1.语法来源 2.关键要素 wireshark中,过滤器有两种,一种是抓包过滤器,一种是显示过滤器! 抓包过滤器适合大网络环境,配置与抓包 ...
- 9.1 ArrayList(集合)的使用,与array(数组)的对比
1.array 和ArrayList的区别? array 数组的长度是固定的,适应不了变化的需求. ArrayList集合的长度可变.大小可变. 2.为什么要用集合,它优点是什么? java是面向对象 ...
- 安卓menu的介绍与使用
菜单之前是用户点击系统的菜单键才展示出来的,后来这个键渐渐被移除,菜单变成了点击任意的view都可以展示.菜单非为3种: 1.Options menu and action bar 选项菜单和操作栏 ...
- webWMS开发过程记录(五)- 详细设计之系统界面框架设计
界面区域划分 使用frameset分了上中下三个区域 上:显示系统名称和用户信息,以及一些提示信息(需通过Ajax定时更新提示信息),显示高度固定 中:再次使用frameset分成左右区域 左:显示导 ...