Browser Security-超文本标记语言(HTML)

重要的4个规则:

[cce]1 &符号不应该出现在HTML的大部分节点中。
2 尖括号<>是不应该出现在标签内的,除非为引号引用。
3 在text节点里面,<左尖括号有很大的危害。 4 引号在标签内可能有危害,具体危害取决于存在的位置,但是在text节点是没有危害的。 [/cce]

文件解析模式

在任何HTML文档中,最开始的用来指示浏览器需要解析的方式,同样也可使用Content-Type头来告诉浏览器。

一般情况下,浏览器中的解析器会尝试恢复大多数类型的语法错误,包括开始和结束标记。

在XML中,是非常严格的,所有标签必须有对应的开始关闭,也可以有自动关闭如也是允许的。

了解HTML解析

在IE浏览器中允许在1中插入NUL字符(0x00),可以绕过非常多的xss过滤器。

如下php代码可把NUL字符插入标签内做测试:

2和4中的空格也可以由tab(0x0B)与换页键(0x0C),2处也可以用/来代替。

5中的”在IE中也可替换成`。

IE当中还有一个特性是当遇到=后面紧跟一个引号的时候会有奇怪的解析。

[cce]Yes, we are still inside a tag!”>

[/cce]

Entity编码

HTML解析器在建立文档树的时候会针对节点内的Entity编码解码后传输。

以下两个表示相同:

[cce]

[/cce]

下面两个例子代码不会执行,因为,编码的是标签本身的结构而非节点内的内容:

[cce]

[/cce]

Fuzzing

对一个普通的HTML进行Fuzzing测试:

[cce]Click me
[/cce]

看一下可以Fuzzing的位置

位置 代码 可能插入或替代的代码
<的右边 <[here]a href="... 控制符,空白符,非打印字符
a标签的后门 同上
href属性中间 所有字符
替换= Union编码符号
替换” 其他引号
>之前 任意字符
/之前 …<[here]/a> 空白符,控制符
/之后 空白符,控制符
>闭合之前 所有字符

可以使用php代码进行快速测试,例如我们对第一个位置(<的右边)进行Fuzzing:

[cce]<'.$character.'a href="http://www.google.com/">‘.$i.’

‘; }
?>
[/cce]

上面的代码只测试了256个字符,如果想要测试Unicode的所有字符,则需要创建65536个链接。

php默认字符是ISO-8859-1作为默认的字符编码,而这种编码只有256个字符,所以单纯的循环65536遍是没用的。

所以采用Entity编码方式循环,解码后输出:

[cce]<'.$character.'a href="http://www.google.com/">‘.$i.’