XSS攻击的简单总结-(基础篇)

声明:本文并非本人原创。因本人水平有限,但是又想看一些深度不会过高,又有一定广度的文章。所以在浏览一些博客后,整理了这篇文章,供广大和我有同样需求的同学参考。

如有侵权,请联系本人,定立即删除。文章末尾附有摘取文章的链接,想深入了解的同学可以再深入学习一下。

目录

一、什么是XSS注入?

二、XSS注入有什么样的影响(XSS攻击的本质)?

三、PoC(Proof of Concept)

四、XSS注入分类

1、存储型 XSS

2、反射型 XSS

3、DOM 型 XSS

五、XSS注入的方式有哪些?

六、XSS 攻击的预防

1. 输入过滤

2. 预防存储型和反射型 XSS 攻击

3. 预防 DOM 型 XSS 攻击

4. 其他 XSS 防范措施(还有很多,可以参考附录的第三篇文章)

七、绕过XSS过滤器的部分方法:

1. 大小写转换

2. 使用引号

3. [/]代替空格

4. tab与回车

5. 对标签属性值进行转码

6. base64加密与解密

7. 拆分跨站


 

 

一、什么是XSS注入?

Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。为了和 CSS 区分,这里把攻击的第一个字母改成了 X,于是叫做 XSS。

二、XSS注入有什么样的影响(XSS攻击的本质)?

  • 恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。
  • 由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,或者利用这些信息冒充用户向网站发起攻击者定义的请求
  • 在部分情况下,由于输入的限制,注入的恶意脚本比较短。但可以通过引入外部的脚本,并由浏览器执行,来完成比较复杂的攻击策略。

三、PoC(Proof of Concept)

我们可以用一段简单的代码,验证和检测漏洞的存在,这样的代码叫做 PoC(Proof of Concept)。验证 XSS 漏洞存在的 PoC 如下:

  • <script>alert(/xss/)</script>       
  • <script>confirm('xss')</script>        
  • <script>prompt('xss')</script>
     

 

四、XSS注入分类

根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM 型三种。

类型 存储区* 插入点*
存储型 XSS 后端数据库 HTML
反射型 XSS URL HTML
DOM 型 XSS 后端数据库/前端存储/URL 前端 JavaScript
  • 存储区:恶意代码存放的位置。
  • 插入点:由谁取得恶意代码,并插入到网页上。

1、存储型 XSS

存储型 XSS攻击步骤

  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

这种攻击常见于:

带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

2、反射型 XSS

反射型 XSS 攻击步骤

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出拼接在 HTML 中返回给浏览器
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

反射型 XSS 漏洞常见于:

通过 URL 传递参数的功能,如网站搜索跳转等。

由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见。

3、DOM 型 XSS

DOM 型 XSS攻击步骤

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL。
  3. 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

三种攻击方式的区别

存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而前两种属于服务端的安全漏洞

五、XSS注入的方式有哪些?

  1. 在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。[<script>alert(/xss/)</script>](蓝色部分为键入内容,这些方式是可以组合使用的,例如:先使用">将 input 的标签进行闭合,然后通过这些方式进行XSS注入)
  2. 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。[<input type="text" οnkeydοwn="alert(/xss/)">]
  3. 在标签的 href、src 等属性中,包含 javascript: 等可执行代码。[<a href="javascript:alert(/xss/)">touch me!</a>]
  4. 在 onload、onerror、onclick 等事件中,注入不受控制代码。[<img src='./smile.jpg' οnmοuseοver='alert(/xss/)'>]
  5. 在 style 属性和标签中,包含类似 background-image:url("javascript:..."); 的代码(新版本浏览器已经可以防范)。[<div style="background-image:url(javascript:alert(/xss/))">]

 

六、XSS 攻击的预防

XSS 攻击有两大要素:

  1. 攻击者提交恶意代码。
  2. 浏览器执行恶意代码。

针对这两大要素,可以总结出下面四大类预防方案:

1. 输入过滤

输入过滤能够在某些情况下解决特定的 XSS 问题,但会引入很大的不确定性和乱码问题。当然,对于明确的输入类型,例如数字、URL、电话号码、邮件地址等等内容,进行输入过滤还是必要的。

产生的问题如下:

  1. 用户的输入内容可能同时提供给前端和客户端,而一旦经过了 escapeHTML(),客户端显示的内容就变成了乱码( 5 &lt; 7 )。
  2. 在前端中,不同的位置所需的编码也不同。

    • 5 &lt; 7 作为 HTML 拼接页面时,可以正常显示:

      <div title="comment">5 &lt; 7</div>
    • 5 &lt; 7 通过 Ajax 返回,然后赋值给 JavaScript 的变量时,前端得到的字符串就是转义后的字符。这个内容不能直接用于 Vue 等模板的展示,也不能直接用于内容长度计算。不能用于标题、alert 等。

2. 预防存储型和反射型 XSS 攻击

存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,攻击者刻意编写的“数据”被内嵌到“代码”中,被浏览器所执行。

预防这两种漏洞,有两种常见做法:

  1. 改成纯前端渲染,把代码和数据分隔开。
  2. 对 HTML 做充分转义。

1) 纯前端渲染

  1. 浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
  2. 然后浏览器执行 HTML 中的 JavaScript。
  3. JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。

在纯前端渲染中,我们会明确的告诉浏览器:

下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。

但纯前端渲染还需注意避免 DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx 等,请参考下文”预防 DOM 型 XSS 攻击“部分)。

在很多内部、管理系统中,采用纯前端渲染是非常合适的。但对于性能要求高,或有 SEO 需求的页面,我们仍然要面对拼接 HTML 的问题。

2.)转义 HTML

如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。

常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 & < > " ' / 这几个字符转义掉,确实能起到一定的 XSS 防护作用,但并不完善:

XSS 安全漏洞 简单转义是否有防护作用
HTML 标签文字内容
HTML 属性值
CSS 内联样式
内联 JavaScript
内联 JSON
跳转链接

所以要完善 XSS 防护措施,我们要使用更完善更细致的转义策略。例如 Java 工程里,常用的转义库为 org.owasp.encoder

HTML 的编码是十分复杂的,在不同的上下文里要使用相应的转义规则。

3. 预防 DOM 型 XSS 攻击

DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。

4. 其他 XSS 防范措施(还有很多,可以参考附录的第三篇文章)

  • HttpOnly:cookie 中设置了 HttpOnly 属性,那么通过js脚本将无法读取到 cookie 信息,这样能有效的防止 XSS 攻击,窃取 cookie 内容。
  • secure:告诉浏览器仅在请求为https的时候发送 cookie ,当请求为 http 时不发送 cookie 。

response.addHeader("Set-Cookie", "uid=112; Path=/; Secure; HttpOnly");

七、绕过XSS过滤器的部分方法:

1. 大小写转换

可以将 payload 进行大小写转化。如下面两个例子。   
<Img sRc='#' Onerror="alert(/xss/)" />
<a hREf="javaScript:alert(/xss/)">click me</a>

2. 使用引号

HTML 语言中对引号的使用不敏感,当我们的代码缺少引号时,某些浏览器会自动添加或补全,但是某些过滤函数是“锱铢必较”。

  1. <img src="#" οnerrοr="alert(/xss/)"/>
  2. <img src='#' οnerrοr='alert(/xss/)'/>
  3. <img src=# οnerrοr=alert(/xss/) />

3. [/]代替空格

可以利用左斜线代替空格。
<Img/sRc='#'/Onerror='alert(/xss/)' />

4. tab与回车

我们可以在一些位置添加 Tab(水平制表符,注意不是空格,空格是不可以的)和回车符,来绕过关键字检测。

  1. <Img/sRc='#'/Onerror    ='alert(/xss/)' />
  2. <A hREf="j    avascript:alert(/xss/)">click me!</a>
  3. <A hREf="j (换行) avascript:alert(/xss/)">click me!</a>

5. 对标签属性值进行转码

  • 对应编码如下:
  字母 ASCII 十进制编码 十六进制编码
1 a 97 &#97 &#x61
2 e 101 &#101 &#x65
3 Tab 9 &#9  
4 换行 10 &#10  
5 回车 13 &#13  
6 SOH   &#01  
7 STX   &#02  
  • 我们可以将3-5插入到任意位置。
  • 将6-7字符插入到头部位置。

           例如:<a href="&#01; j&#97; v&#x6; s&#9; c&#10; r&#13; ipt:alert(/xss/)">click me!</a>

6. base64加密与解密

先对 XSS 注入的代码进行 base64 加密,将加密后的代码放入 atob 函数中进行解密,最后可以再借助eval来执行被恶意注入的代码

<input type="text" name="p1" size="50" value="guangtailang" ><script>eval(atob('YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=='));</script> ">

7. 拆分跨站

  1. <script>z='alert'</script>
  2. <script>z=z+'(/xss/)'</script>
  3. <script>eval(z)</script>
  4. <script>alert(/xss/)</script>

摘自:

Cookie中的httponly的属性和作用

XSS -- 三种基本漏洞 (浅谈)

前端安全系列(一):如何防止XSS攻击?

猜你喜欢

转载自blog.csdn.net/qq_44647809/article/details/115227862