一、前言
XSS(cross-site scripting跨域脚本攻击)攻击是最常见的Web攻击,其重点是“跨域”和“客户端执行”。
黑客往HTML页面中或者DOM中注入恶意脚本,从而当用户在浏览器页面的时候利用注入的恶意脚本对用户实施攻击的一种手段。
二、影响
- 窃取当前站点的私密信息,例如cookie
- 恶意脚本可以通过document.cookie读取当前页面的cookie信息,然后通过CORS策略基于Ajax请求将cookie发送给远端的黑客服务器,黑客拿到用户的cookie数据之后,如果这个网站的身份认证是基于cookie+session那一套做的,那么黑客便可以模拟用户登录,向源服务器发起转账等请求
- 操作DOM伪造文档,生成广告弹窗等
- 恶意脚本拥有对于当前页面DOM的全部操作权限,黑客完全可以先将当前网站的界面屏蔽然后伪造一个登录页面,等用户输入用户名和密码等敏感信息之后通过Ajax请求发送至自己的黑客服务器。
- 监听用户行为
- 恶意脚本可以通过addEventListener接口来监听当前页面的键盘事件,进而通过事件对象获取到用户的个人信息,将其通过Ajax请求发送给黑客服务器等。
二、攻击方式
XSS 攻击根据攻击方式可以分成三类
1、反射型
利用网页的检索功能
反射性XSS攻击的一个前提是黑客知道当前站点某个网络请求需要用户携带参数,并且服务器会将用户发送的参数又返回给用户。
反射性XSS攻击和存储型XSS攻击的区别在于都没有对用户的输入做合格的关键字过滤,但是前者不存储用户输入,后者会将用户输入存储在服务器上。
攻击步骤:
- 用户将恶意脚本当做请求的一部分发送给服务器
- 服务器在收到这个请求后,又将恶意脚本返回给客户端
- 当浏恶意脚本被浏览器执行的时候就产生了攻击
2、存储型
攻击步骤:
- 黑客先利用站点的漏洞将恶意脚本提交到站点的服务器,服务器 未对输入做安全检验 ,直接存储到数据库;
- 用户向网站请求了包含恶意脚本的HTML页面,浏览器解析HTML页面的时候就会执行恶意脚本;
- 恶意脚本读取到当前站点的隐私数据如 cookie 、用户信息 等通过Ajax 发送到黑客服务器;
- 黑客利用用户的 cookie 等信息在其他机器上登录该用户的账号,然后执行一些恶意攻击操作。
3、DOM型
网页的源码因为同时存在可以操作的属性和方法,导致网页文档结构被修改,这就是DOM 型 XSS 攻击
浏览器和服务器传输的过程中被黑客劫持,然后往HTML页面的DOM中插入恶意脚本或者修改页面内容,用户浏览器在加载被插入恶意脚本的 HTML 之后,恶意脚本执行并完成攻击
三、如何防御
-
服务器对用户提交的数据进行关键字的 过滤或转码,这样处理后返回给客户端的时候,浏览器只会将其当做普通的文本。
- 对HTML中可以获取资源的标签文本如:script、link、style、meta等文本进行过滤
- 对一些HTML字符串、js字符以及URL中携带的字符进行编码
-
使用浏览器自带的CSP策略
-
CSP策略其主要目的就是为了防止发生XSS攻击的,它的核心是由开发者决定哪些资源可以被当做第三方资源嵌入当前页面,这样就等于给当前站点开了一个第三方资源的白名单,不在这个白名单上的资源浏览器就算获取到也不会加载执行,可以在很大程度上降低XSS的风险。
-
主要内容:
- 限制加载其他站点的任意资源。就算黑客往当前页面中嵌入了一个js文件,此文件由于和当前站点不同源也是无法加载执行的。
- 禁止执行内联脚本。黑客不能通过嵌入一个内联脚本来发起攻击。
- 禁止向其他站点提交数据,这样就算黑客的恶意脚本执行成功用户的个人信息也无法被发送出去。
- 提供当攻击发生时候的上报机制,帮助我们主动发现XSS攻击。
-
3、使用http-only
- 有些XSS攻击的主要目的就是窃取用户的cookie,然后通过Ajax请求将其发送到黑客服务器。当然这是恶意脚本已经注入的前提下,对此我们可以要求服务端对于某些重要的cookie在设置响应头set-cookie的时候,将其属性HttpOnly设置为true。
- 属性设置HttpOnly为true的cookie,浏览器不允许脚本通过document.cookie方法对cookie进行读取和写入,这样就算恶意脚本注入之后也无法将用户的cookie提交给黑客服务器,也就避免了后续的攻击。
四、总结
- XSS攻击大多数情况下都是服务端没有做好关键字的过滤和校验,从而导致恶意脚本被注入。
- 对于一些用户输入的内容表单,前端需要对用户的输入进行合法性的校验,但是这种校验一般是基于业务的校验,因为黑客可以通过接口的方式绕过前端界面完成脚本注入,所以我个人认为XSS攻击的主要缺口在于服务端。
- 相对比服务端对用户输入做安全校验,前端也应该对服务器返回的数据进行校验。