vlambda博客
学习文章列表

了解一下前端安全知识:XSS和CSRF

点击 上方蓝字 关注我们


阅读本文大概需要5分钟。


今晚想写这篇文章是有原因的,其实之前老陈也了解过前端的一些安全,但是了解得不够深刻吧,导致最近一次小面试错漏百出,所以接着这个时机,补一补自己的前端安全的知识。

一、XSS是个啥玩意

今天我们了解一下什么是XSS,俗称跨站脚本攻击,也就是你的页面有一些漏洞,可以让攻击者注入代码,达到窃取信息的目的。

例如:能够获取页面的dom,cookie,localStorage,发送请求等等。

二、XSS的类型

这里当时在面试的时候一顿乱说,感觉还是可以整理一下,虽然有一些说的有点错误。

第一种就是反射类型,可以通过URL注入参数,注入之后,我们可以获取到当前页面的一些关键信息,这种反射类型的注入,不是持久性的

第二种就是存储型注入,存储到数据库后读取注入。

第三种就是基于DOM,被执行的恶意脚本会修改页面脚本结构。

三、XSS的注入点

那么我们可以去XSS注入的点哪里呢?第一个是HTML的节点内容或者属性,第二个是Javascript代码,第三个富文本。

我们可以探讨一下,关于一些防御的手段。

如何防止反射性的XSS,可以通过浏览器的防御,只能防御注入到HTML的节点内容或者属性的XSS。

那么我们在一些字符串模板使用的过程中,可能会输入<script></script>这种就会存在被浏览器执行的风险,所以我们需要将字符串<和>转义为&lt和&gt。

然后就是需要防御HTML属性。

<template>  <img :src="image" /></template><script>  image = 'www.qq.com/a.pngonload="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如果用,必须提前对内容进行过滤。

四、CSRF是个啥东东

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的方案来防御,具体如何实现,看各位读者去实现了。


   扫描关注

老陈说前端

想象不到的干货