前言
谈到前端安全,大家都会想到XSS,CSRF,SQL注入等攻击。
今天咱们来聊聊XSS攻击!
一、什么是XSS攻击
XSS攻击,英文全称是Cross Site Scripting,翻译过来的意思就是跨站脚本攻击。它的缩写是CSS,由于跟咱们平时写的层叠样式表CSS混淆,所以也就简称为了XSS。
所谓 “跨站脚本攻击”,也就是一种利用恶意的脚本来进行攻击的方式。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行,从而达到攻击的目的。
XSS的本质就是:攻击者的恶意代码未经过滤,与正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。
XSS攻击的危害系数是很高的,如果没有防范好,攻击者便可以利用这些恶意脚本,来获取用户的敏感信息如Cookie,SessionID等,进而危害数据安全。
那么问题来了,攻击者是通过什么样的方法来 “注入” 恶意脚本的呢?接着往下看~~~
二、XSS分类
根据攻击的来源,XSS攻击可分为存储型、反射型、DOM型。
1. 存储型XSS
- 完成存储型XSS攻击,可分为两步:
- 攻击者在目标网站上提交了恶意内容到服务器,服务器没有识别,并保存了该恶意内容到服务器;
- 正常用户进入该网站,访问服务器,服务器在不知情的情况下,给予了之前的恶意内容,从而让正常用户遭到攻击;
举个例子:
有一个论坛系统,发布的帖子里用户可进行留言,有一天小黄发布了一个新帖子A,这时恶意用户小张发现了该系统没有进行XSS防护,因此在A帖子的留言区中输入了<script>alert(1)</script>
,并提交,此时服务器便直接将该内容存入了数据库。之后,其他用户在访问到帖子A时,服务器将其他正常内容以及小张提交的恶意内容混在一起,返回给了用户,并执行。当执行到小张提交的恶意内容时,该恶意代码就会被执行了。因此,在之后每个正常用户只要访问到该帖子时,就会执行该恶意代码。也就容易造成蠕虫。
2. 反射型XSS
- 原理:攻击者在URL中插入XSS代码,服务端将URL中的XSS代码输出到页面上;
- 实现:攻击者将带有XSS代码的URL发送给用户,用户点击打开后,网站服务端将恶意代码从URL中取出,拼接在 HTML 中返回给浏览器,用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行;
举个例子:
我们这里就拿百度来说,当然百度肯定是有做防护的。我们现在就假设他没有做防护。首先,该网站中有搜索框,我们可以在搜索框中输入信息,进行搜索;
我们输入NBA,进行搜索;可以看到我们搜索的信息,作为参数放到了URL中;并且无论你输入任何关键字,它都将随搜索结果一起被显示在网页上;
此时,我作为恶意用户,要进行XSS攻击,我就把该wd的参数值改为<script>alert(1)</script>
,然后转发给其他用户,当其他用户一点击该链接时,就会出现以下情况,此时在没有做XSS防护的情况下,该恶意代码就会被执行。
-
反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。
-
反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。
3. DOM型XSS
DOM型XSS会相对比较少一些,它是在纯前端完成的,并没有涉及到服务器。
它的实现是:
- 攻击者构造出特殊的URL,其中包含恶意代码;
- 用户打开带有恶意代码的URL;
- 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行;
这看着和反射型XSS很相似,但DOM型XSS跟前两种的区别是:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。
咱们看个例子(这是Pikachu系统中的例子):
- 我们在输入框中输入1111提交之后我们回看到这个参数是通过url传递的,看着很像反射型XSS对吧,其实他并没有把参数传到后台只是在前台显示了;
- 查看它页面源代码
- 此时我们在输入框中,输入 #’ οnclick=“alert(111)”>,那么最终会变成<a href=’#’ οnclick=“alert(111)”>>就让往事都随风,都随风吧,最终点击a标签时,就会出现弹框;
- 最终将该链接发给受害者,就可以造成攻击啦。
DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。
三、XSS攻击的预防
通过以上的信息介绍可以得知,XSS攻击的两大要素就是:
- 攻击者提交恶意代码
- 浏览器执行恶意代码
目前一些流行的浏览器中,都已经内置了一些对抗XSS的防护措施。但这远远是不够的,那么平时我们应该如何进行XSS防护呢?XSS的防护有很多的方式,这里讲讲较为常见的~~~
1. 输入过滤(转义)
这里有两种方式:
- 在用户提交时,由前端进行过滤,然后提交到后端;
- 在后端写入数据库前,对输入进行过滤。
输入过滤的方式是最常见的,但也并非完全没有弊端。对第一种来说,在前端进行输入过滤,很有可能攻击者就会绕过前端过滤,从而提交恶意代码(不过现在也有很多比较成熟的xss库了,各种能绕过的方式,都能被解决~~~)。对第二种来说,当我们的输入没有明确输入类型的时候,就会产生混乱;比如用户输入了 3 < 5,经过转义得 3 < 5,如果是作为html拼接到页面中,可以正常显示;如果是作为JavaScript的变量,就会产生错误。所以对于明确的输入类型,如:数字、URL、电话号码、邮件地址等,进行输入过滤还是很有必要的。
2. 其他安全措施
- 对输入的内容长度进行限制,虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度,减小风险;
- 使用HTTP-only Cookie::禁止 JavaScript 读取某些敏感 Cookie信息,攻击者完成 XSS 注入后也无法窃取此 Cookie;
- 验证码:防止脚本冒充用户提交危险操作;
- 禁止加载外域代码,防止复杂的攻击逻辑;
- …
对于XSS攻击,有很多的防护方式,在我们平时的开发中,要记住,只要是用户输入的数据,就不可能百分百安全,所以在平时开发中,还是需要谨慎一些,以免造成不必要的损失~ 今天就聊到这里啦!!!
参考资料:https://tech.meituan.com/2018/09/27/fe-security.html