本篇博客主要总结一下什么是XSS
攻击,并且如何防范XSS
攻击。
一、什么是XSS攻击XSS
攻击中文名称为:跨站脚本攻击
,XSS
的重点不在于跨站,而在于脚本的攻击。XSS攻击的工作原理
:攻击者会在web页面中插入一些恶意的script
代码。当用户浏览该页面的时候,那么嵌套在该页面的代码就会执行,因此会达到攻击用户的目的。XSS的分类
:XSS
攻击最主要分为如下几类,反射型
,存储型
,DOM-based型
。反射型和DOM-based型
可以归类于非持久性XSS
攻击。存储型
可以归类于持久性XSS
攻击。
二、反射型XSS反射型XSS攻击原理:
攻击者发送给被攻击者一个邮件信息或者链接,当被攻击者点击并访问该链接时,此时就会向攻击者的目标服务器发起请求,此时根据请求返回相关的script
代码,当浏览器解析这些script
代码时,此时代码就会在浏览器执行,造成用户被攻击。下面我们看一个小例子
,模拟一下xss
攻击。
上述就是一个简单的反射XSS
攻击的例子。
当我们访问一个网站时,此时如果攻击者在该网站上设置了一个恶意连接,此时当我们点击该链接时,就会向攻击者服务器发起请求,返回对应的脚本,此时当浏览器加载该脚本文件时,就会出现token
或者cookie
等信息的泄漏。
三、存储XSS攻击存储型XSS攻击
是持久性攻击方式,因为该攻击的代码会提交到服务器中的数据中进行保存。此时我们可以看一个例子:比如说存在一个博客网站,每一个用户都可以在该博客网站上发表博客。此时当用户写入了一些js
代码例如:
<script>window.open("?params=" + document.cookie)</script>
此时如果不加处理,就会保存在服务器的数据库中,此时当其他用户访问该博客时,用户的浏览器就会执行这段script代码,此时本地的cookie
就会发送到这个网址上,造成cookie泄漏。攻击者就会拿到cookie冒充用户身份,登录账号。
如何解决呢?
预防存储XSS攻击
:可以在后端做一些过滤,也可以在前端做一些转义特殊字符之类的。
四、DOM-based型XSS攻击
我们的客户端的js可以对DOM节点进行动态的操作,比如插入,修改页面的内容。比如说客户端从url中提取数据并且在本地执行,如果用户在客户端输入的数据包含了恶意的js脚本的话,但是这些脚本又没有做过任何过滤处理的话,那么我们的应用程序就有可能受到DOM-based XSS
攻击,因此DOM型XSS攻击步骤如下。1、
攻击者构造出特殊的url
,其中包含恶意代码。2、
用户打开带有恶意代码的url。3、
用户浏览器接收到响应后解析执行,前端取出恶意代码并执行。4、
恶意代码窃取用户数据并且发送到攻击者的网站,冒充用户的行为。DOM-based xss
和之前两种xss攻击的区别,DOM-based xss
是前端的漏洞,但是前面两个是服务器的漏洞。
下面看一下简单案例:
五、XSS攻击的预防
关于前面我们知道了XSS
攻击形成的存在两个原因,一个是攻击者提交恶意代码
,另一个是浏览器执行恶意代码
。5.1、输入过滤
针对第一种输入过滤,我们可以思考一下,如果我们在前端进行过滤,也就是当用户准备提交时进行过滤如何?肯定是不行的,如果在用户提交时在前端过滤,那么用户可能会不通过前端,而直接去请求接口,这样就无法阻止攻击者提交恶意代码。如果在代码在后端准备写入数据库中进行定义如何?答案也是不行的,举一个例子,如果我们提交5 < 7
,此时如果在准备插入数据库进行ecapeHTML
编码,此时就会编译成5 < 7
,此时当前端请求数据时,此时返回页面是5 < 7
是没有问题的,但是如果在像vue这些框架中使用,则无法进行转义,任然显示5 &It; 7
。所以输入过滤是不行的。但是对于一些特别的输入比如电话号码,邮箱地址等等信息可以使用输入过滤。此时我们应该将侧重点放在防止浏览器恶意执行代码
。5.2、预防存储型和反射型 XSS 攻击
存储型和反射型XSS
都是在服务端取出恶意代码,出入到相应HTML中的,攻击者可以编写数据被内嵌到代码
中,被浏览器执行,所以为了预防这两个漏洞,采用的常见做法为:1、改为纯前端渲染,把代码和数据分开
,2、对HTML做充分的转义
。5.2.1、纯前端渲染
浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
然后浏览器执行 HTML 中的 JavaScript。
JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。浏览器不会被轻易的被欺骗,执行预期外的代码了。5.2.2、转义HTML
如果需要拼接HTML是必要的话,就需要采用合适的转义库,对HTML模板各处插入点进行充分的转义。常用的模板引擎,如 、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 & < > " ’ / 这几个字符转义掉,确实能起到一定的 XSS 防护作用。5.3、预防DOM型XSS攻击
DOM型XSS攻击
,实际上就是网站前端javascript
代码本身不够严谨,把不可信的数据当做代码执行了。在使用.innerHTML
,.outerHTML
,()
时要特别小心,不要把不可信的数据当做HTML插入到页面上,而应尽量使用.textContent
,.setAttribute
。
六、其他的XSS攻击
虽然在渲染页面和执行javascript
时,通过谨慎的转义可以防止xss的发生,但完全依赖开发的严谨任然是不够的,以下介绍一些通用的方案,可以降低xss带来的风险和后果。6.1、CSP
Content Security Policy:
严格的CSP
在XSS
的防范中可以起到以下作用:
禁止加载外域代码,防止复杂的攻击逻辑。
禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
合理使用上报可以及时发现 XSS,利于尽快修复问题。
6.2、输入内容长度控制
对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止XSS发生,但可以增加xss攻击的难度。
6.3、其他安全措施
http-only cookie:禁止javascript读取某些敏感的cookie,攻击者完成xss注入后无法窃取此cookie.
验证码:防止脚本冒充用户提交危险操作。
七、XSS攻击总结1、XSS 防范是后端 RD 的责任,后端 RD 应该在所有用户提交数据的接口,对敏感字符进行转义,才能进行下一步操作。
上面描述是错误的,因为防范存储型和反射型xss是后端的责任,但是DOM型的xss不发生在后端而是前端的责任,防范xss是前端和后端共同的责任。
转义应该在输出HTML进行转义,而不是在提交用户输入时。
2、所有要插入到页面上的数据,都要通过一个敏感字符过滤函数的转义,过滤掉通用的敏感字符后,就可以插入到页面中。
不正确。 不同的上下文,如 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等,所需要的转义规则不一致。 业务 RD 需要选取合适的转义库,并针对不同的上下文调用不同的转义规则。