`
highfly-s
  • 浏览: 96803 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

HTML 与javascript自解码机制

 
阅读更多

关于这个自解码机制,我们直接以一个例子(样例0)来进行说明:
<input type="button" id="exec_btn" value="exec" onclick="document.write ('<img src=@ onerror=alert(123) />')" />

 

我们假设document.write里的值是用户可控的输入,点击后,document.write出现一段img HTML,onerror里的JavaScript会执行。此时陷阱来了,我们现在提供一段HtmlEncode函数如下(样例A):
<script>
function HtmlEncode(str) {
    var s = "";
    if (str.length == 0) return "";
    s = str.replace(/&/g, "&amp;");
    s = s.replace(/</g, "&lt;");
    s = s.replace(/>/g, "&gt;");
    s = s.replace(/\"/g, "&quot;");
    return s;
}
</script>
<input type="button" id="exec_btn" value="exec" onclick="document.write (HtmlEncode('<img src=@ onerror=alert(123) />'))" />

 

我们知道HtmlEncode('<img src=@ onerror=alert(123) />')后的结果是:
&lt;img src=@ onerror=alert(123) /&gt;

 

这个样例A点击后会执行alert(123)吗?下面这个呢(样例B)?
<input type="button" id="exec_btn" value="exec" onclick="document.write ('&lt;img src=@ onerror=alert(123) /&gt;')" />

 

在样例A和样例B中,document.write的值似乎是一样的?实际结果是样例A点击不会执行alert(123),而是在页面上完整地输 出<img src=@ onerror=alert(123) />,而样例B点击后会执行alert(123)。

 

我们要告诉大家的是,点击样例B时,document.write的值实际上不再是:
&lt;img src=@ onerror=alert(123) /&gt;

 

而是:
<img src=@ onerror=alert(123) />

 

我们可以这样论证:
<input type="button" id="exec_btn" value="exec" onclick="x='&lt;img src=@ onerror=alert(123) /&gt;';alert(x);document.write(x)" />

 

看弹出的x值就知道了,如图6-1所示。

 

出现这个结果的原因如下:

 

onclick里的这段JavaScript出现在HTML标签内,意味着这里的JavaScript可以进行HTML形式的编码,这种编码有以下两种。

 


 

 

进制编码:&#xH;(十六进制格式)、&#D;(十进制格式),最后的分号(;)可以不要。
HTML实体编码:即上面的那个HtmlEncode。

 

在JavaScript执行之前,HTML形式的编码会自动解码。所以样例0与样例B的意义是一样的,而样例A就不一样了。下面我们继续完善这些例子。

 

上面的用户输入是出现在HTML里的情况,如果用户输入出现在<script>里的JavaScript中,情况会怎样,代码如下:
<input type="button" id="exec_btn" value="exec" />
<script>
function $(id){return document.getElementById(id);};
$('exec_btn').onclick = function(){
 document.write('<img src=@ onerror=alert(123)/>');
 //document.write('&lt;img src=@ onerror=alert(123) /&gt;');
};
</script>

 

这样是可以执行alert(123)的,如果用户输入的是下面的内容:
&lt;img src=@ onerror=alert(123) /&gt;

 

结果与样例B一样:这段HTML编码的内容在JavaScript执行之前自动解码吗?答案是不会,原因是用户输入的这段内容上下文环境是 JavaScript,不是HTML(可以认为<script>标签里的内容和HTML环境毫无关系),此时用户输入的这段内容要遵守的是 JavaScript法则,即JavaScript编码,具体有如下几种形式。

 

Unicode形式:\uH(十六进制)。

 

普通十六进制:\xH。

 

纯转义:\'、\"、\<、\>这样在特殊字符之前加\进行转义。

 

比如,用户输入被转义成如下形式:
\<img src\=@ onerror=alert\(123\) \/\>

 

这样的防御毫无意义,在JavaScript执行之前,这样的转义会自动去转义,alert(123)照样执行。同样,下面这样的JavaScript编码也毫无意义:
<img src=@ onerror=alert(123) />
-->
\u003c\u0069\u006d\u0067\u0020\u0073\u0072\u0063\u003d\u0040\u0020\u006f\u006e\u0065\u0072\u0072\u006f\u0072\u003d\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0032\u0033\u0029\u0020\u002f\u003e
\x3c\x69\x6d\x67\x20\x73\x72\x63\x3d\x40\x20\x6f\x6e\x65\x72\x72\x6f\x72\x3d\x61\x6c\x65\x72\x74\x28\x31\x32\x33\x29\x20\x2f\x3e

 

在JavaScript执行之前,这样的编码会自动解码。

通过这几个样例,我们可以知道在HTML中与在JavaScript中自动解码的差异。如果防御没区分这样的场景,就会出问题

 

具备HtmlEncode功能的标签

 

上面这些例子中的信息量很大,是理解透DOM XSS的基础,下面我们进一步看看不同标签之间存在的一些差异,看下面这段代码:
<script>function $(id){return document.getElementById(id);};</script>
<input type="button" id="exec_btn" value="exec" onclick="$('i1'). innerHTML='<img src=@ onerror=alert(123) />';alert($('i1').innerHTML);" />
<input type="button" id="exec2_btn" value="exec2" onclick="$('i2'). innerHTML='<img src=@ onerror=alert(123) />';alert($('i2').innerHTML);" />
<textarea id="i1" style="width:600px;height:300px;"></textarea>
<div id="i2"></div>

点击exec_btn和点击exec2_btn的效果一样吗?如图6-2所示。


 

左图是点击exec_btn的效果,右图是点击exec2_btn的效果,前者进行了HtmlEncode编码。这是由<textarea>标签本身的性质决定的,HTML 在<textarea>中是不解析的。同理可推,这样的标签还有:
<title></title>
<iframe></iframe>
<noscript></noscript>
<noframes></noframes>

这些标签在本章开头部分曾提到过,不过少了以下两个:
<xmp></xmp>
<plaintext></plaintext>

<xmp>没有HtmlEncode功能,<plaintext>在Firefox与Chrome下有差异,Firefox下不会进行HtmlEncode编码,而在Chrome下会,这样的差异有时候会导致安全问题。

 注:

上面这个样例不用在IE下测试,因为IE有解析差异,会导致代码不执行。

2009年,我们发现WebKit内核的浏览器有一个安全差异,这个漏洞简述为:

获取textarea标签的innerHTML内容时,内容没有被编码,导致安全隐患产生。

...

如曾经的QQ滔滔做HtmlEncode采取了如下方式:
< script >
function HTMLEncode(s) {
    var html = "";
    var safeNode = document.createElement("TEXTAREA");
    if (safeNode) {
        safeNode.innerText = s;
        html = safeNode.innerHTML;
        safeNode = null;
    }
    return html;
}
var tmp = '<iframe src=http://baidu.com>';
alert(HTMLEncode(tmp));
</script>

因为textarea在HTML中的权重很高,允许html标签出现在<textarea></textarea >之间,所以这种做法本没有任何问题,但因为WebKit存在此缺陷,导致在Maxthon 3.0极速模式、Chrome和Safari的所有版本中,本应该是绝对安全的代码变成了恶意代码,并可以随意执行XSS语句。

这种差异导致这个网站在WebKit内核的浏览器下出现了DOM XSS漏洞

分享到:
评论

相关推荐

    HTML5高级程序设计

    本书首先介绍了html5 的历史背景、新的语义标签及与以往html 版本相比的根本变化,同时揭示了html5 背后的设计原理。从第2 章起,分别围绕构建令人神往的富web 应用,逐一讨论了html5 的canvas、geolocation 、...

    完整版《HTML5高级程序设计》2

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 163 ...

    完整版《HTML5高级程序设计》5

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 163 ...

    完整版《HTML5高级程序设计》4

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 163 ...

    HTML5程序设计(第2版).[荷]Peter Lubbers(带详细书签).pdf

    《深入HTML5编程(第 2版)》首先介绍了HTML5的历史背景、新的语义标签及与以往HTML版本相比的根本变化,同时揭示了HTML5背后的设计原理。本书在上一版的基础上新增了SVG和拖放API相关内容,并对部分内容进行了更新。...

    完整版《HTML5高级程序设计》3

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 163 ...

    HTML5高级程序设计.part5

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 ...

    HTML5高级程序设计.part4

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 ...

    HTML5高级程序设计.part1

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 ...

    HTML5高级程序设计.part2

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 ...

    HTML5高级程序设计.part3

    8.2.3 多个JavaScript文件的加载与执行 160 8.2.4 与HTML5 Web Workers通信 160 8.3 编写主页 161 8.3.1 处理错误 161 8.3.2 HTML5 Web Workers 162 8.3.3 HTML5 Web Workers的嵌套使用 162 8.3.4 使用定时器 ...

    php网络开发完全手册

    12.3.1 在HTML中嵌入JavaScript 184 12.3.2 变量 185 12.3.3 注释 185 12.3.4 函数的定义与调用 186 12.3.5 条件语句 186 12.3.6 循环语句 189 12.3.7 对象 191 12.3.8 事件 192 12.4 PHP动态生成JavaScript代码 193...

    JAVA上百实例源码以及开源项目源代码

    两个目标文件,自绘button。 Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟  用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven Bean ...

    java源码包---java 源码 大量 实例

    两个目标文件,自绘button。 Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟  用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven Bean ...

    JAVA上百实例源码以及开源项目

    两个目标文件,自绘button。 Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟  用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven Bean ...

    基于E2EE的无状态认证JsonWebToken算法、常用Web算法模块-易语言

    4、更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可. 5、去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的...

    java源码包2

    两个目标文件,自绘button。 Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟  用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven ...

    java源码包3

    两个目标文件,自绘button。 Java圆形电子时钟源代码 1个目标文件 内容索引:JAVA源码,系统相关,电子钟  用JAVA编写的指针式圆形电子钟,效果图如下所示,其实代码很简单,希望对你有帮助。 Message-Driven ...

Global site tag (gtag.js) - Google Analytics