对dom xss的一次记录

Posted by grt1stnull on 2018-07-07

一提起xss攻击,很多人都会想到它有三种类型,分别是反射型、存储型和dom xss。前两者大家都知道也很好理解,但是你说dom xss是什么呢?你真的真的知道吗?

0x00.开端

某一天,一个学弟突然问我“dom xss是什么啊,使用到onerror的吗”。于是回到前言,在我学xss的时候,确实是三种类型,很容易理解的反射型和存储型,但是dom xss是个什么东西呢?html不也是一个dom嘛,比如<html><head></head><body></body></html>,既然名字叫dom xss,难道无论反射型还是存储型都是dom xss?

于是疑惑的我开始和学弟一起学习。通过搜索引擎,我找到了满意的答案:DOM Based Cross-site Scripting Vulnerability。在这个网页里句子不多,但是讲解确是很清晰很透彻。于是我知道dom xss是什么了。

看官请注意了,下面我将概括dom xss:

dom xss出现在dom中,却不是html的一部分。在反射型与存储型xss中,你可以在服务器响应的html源码中观察到xss payload,但是在dom xss中,服务器返回的html页面和正常页面没有什么区别,在页面源码中看不到payload,只能在网页运行时调查网页才能发现。

上一段是不是看起来特别厉害,这个不是我总结的,是我从那个网友中总结出来的。简单来说就是,在dom xss中,网页的源码和正常网页的源码是一样的,因为它是通过网页运行(即浏览器解析渲染html)来触发的,只有网页运行后才能注意到。运行时改变网页内容的,最常见的就是js。所以最简单的例子,网页通过js来输出信息,比如url的参数、服务器请求的结果(ajax),如果对html实体没有转义,就有可能引入新的dom,比如<script>...</script>

于是就很好理解了,特性如下:

  • payload不出现在服务器返回的网页源码中
  • 浏览器渲染时触发(比如运行js
  • 动态改变网页,相当于插入新的dom

0x01.发展

通过学弟的提问,我学习到了新的知识。但是你以为这就结束了吗,答案是并没有。

就在前几天,我调试我的网页时,突然发现,怎么点击某个按钮之后,我的前端会突然改变呢?

赶紧打开开发者模式,监听network。原来在点击按钮后,会突然加载新的css,改变了前端的样式,所以前端变了。

那么我这个按钮是做什么的呢?这个按钮提交参数,通过ajax拉取结果,并将结果以浮窗的形式展示出来。

于是我赶紧进入数据库,看看我这个按钮输出的结果是什么内容。

原来我输出的内容是一段html的代码。

0x02.高潮

那么问题来了,作为一名安全人员,我怎么就没有/忘记对输出做过滤呢?

首先,如今开发网站内容,使用框架比较多,敏捷开发,很省心。而通常,web框架都会有html模板,将动态内容发到http模板中进行展示。当然动态内容都是进行实体转义的,如果你需要输出html便签,只有手动的指定禁止转义。

在这种情况下,安全性无疑是提高了很多。前端的输出自动进行转义,再也不用担心产生xss了(误。

那么我这里怎么就产生了呢?

为了对用户友好,我没有使用打开新网页的方式,而是采用ajax的方式,提交请求后,将返回的结果展示在网页中。

所以嘛,就是我对返回的内容没有做过滤,因为忽略了会展示在html中而且内容是可控的。

0x03.结局

知道了要对用户可控的内容输出做过滤后,用函数对html进行转义即可。比如golang的html.EscapeString(content)、python3的import html;html.escape(content)

经过一次学习和亲身的经历,我想我对dom xss已经有了一定的理解(捂脸

以及,就算web框架在一定程度上提供了安全性,但是依旧存在产生漏洞的可能。

并且,我真的要细心了(捂脸

0x04.参考

DOM Based Cross-site Scripting Vulnerability