今晚想写这篇文章是有原因的,其实之前老陈也了解过前端的一些安全,但是了解得不够深刻吧,导致最近一次小面试错漏百出,所以接着这个时机,补一补自己的前端安全的知识。
今天我们了解一下什么是XSS,俗称跨站脚本攻击,也就是你的页面有一些漏洞,可以让攻击者注入代码,达到窃取信息的目的。
例如:能够获取页面的dom,cookie,localStorage,发送请求等等。
这里当时在面试的时候一顿乱说,感觉还是可以整理一下,虽然有一些说的有点错误。
第一种就是反射类型,可以通过URL注入参数,注入之后,我们可以获取到当前页面的一些关键信息,这种反射类型的注入,不是持久性的
。
第三种就是基于DOM,被执行的恶意脚本会修改页面脚本结构。
那么我们可以去XSS注入的点哪里呢?第一个是HTML的节点内容或者属性,第二个是Javascript代码,第三个富文本。
如何防止反射性的XSS,可以通过浏览器的防御,只能防御注入到HTML的节点内容或者属性的XSS。
那么我们在一些字符串模板使用的过程中,可能会输入<script></script>这种就会存在被浏览器执行的风险,所以我们需要将字符串<和>转义为<和>。
<template>
<img :src="image" />
</template>
<script>
image = 'www.qq.com/a.png" onload="alert(1)'
</script>
// 以上是伪代码
// 输出结果
<img src="www.qq.com/a.png" onload="alert(1)">
从输出结果我们就能看到,这样的注入方式,会导致执行onload的事件,十分危险,所以我们也是通过转义的方式来处理,先转义“,同时转义‘,就可以了。
我们再来看看另外一种比较常见的情况,就是通过url的方式来注入js代码,这个当时我在说的时候,把他说成可以通过参数,来获取页面的关键信息,没说明白,导致面试官可能理解有误,所以我也顺着他的思路说下去另外一种的方式,这个下面会讲。
假如我们访问的是: www.qq.com?id=222";alert(1);"
let id = getQuery('id')
let id = "1"; alert(1);""
所以我们可以通过对数据进行序列化 JSON.stringify(str),这样就解决这个问题了。
我们说了两个注入了,我们接着说富文本的风险。我们经常会使用v-html这个来用于渲染dom节点,这时候可能就有问题,假如我们写了这样的代码<a onmouseover=alert(document.cookie)>点击</a> 那这样的话就会触发alert弹窗,所以防御富文本其实是一个比较复杂的事,所以我们需要特殊处理HTML的代码,其实也可以通过第三方的库来实现,不用自己造轮子了,如JS-XSS。
当然我们经常使用的VUE中已经有XSS防御了,比如URL参数,尽量用{{}}这样经过了字符串化,浏览器不会对其中的内容进行执行操作。
重要的事情说三遍:尽量少用v-html ,尽量少用v-html,尽量少用v-html如果用,必须提前对内容进行过滤。
Croos Site Request Frogy指的是跨站请求伪造。与XSS不同的是,他会通过网站B来对目标网站A伪造请求。
例如 登陆了网站A之后,点击了一个恶意的链接B,B请求了网站A的下单接口,结果在网站A生成了一个 订单,其背后的原理就是网站B通过表单、get请求来伪造网站A的请求,这时候请求会带上网站A的cookies,若登陆态保存在cookies中,就是实现了伪造攻击。
发生的事情就比如说用户的登陆态被盗用,完成了业务的请求。
它的特点也很明显了,就是伪造请求不经过网站A,伪造请求的域名不是网站A
那对它的防御相对简单一些,能不使用GET请求就不使用。
还有就是添加验证码,因为伪造请求不经过A,所以我们需要验证一下,这样通过验证的请求才合法。
针对第二个伪造请求不是A的情况,那么我们将cookies设置为sameSite为strict,只有同源网站的请求才会带上cookies。
验证reffer ,后端可以通过referrer来验证。
验证token,服务端随机生成token,保存在服务器中的session中,同时保存到客户端中,客户端发送请求时,把token带到HTTP请求头或者参数中,服务端验证一下,token与session中是否一致。
最后一种方式的话,就是通过JWT的方案来防御,具体如何实现,看各位读者去实现了。