欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

一次对浏览器解析和XSS的深度探究

来源:本站整理 作者:佚名 时间:2020-01-28 TAG: 我要投稿

一、需要了解的一些基本知识
为什么要进行编码?
主要是因为某些数据不适合传输。原因多种多样,如 Size 过大,包含隐私数据,另外重要的一点就是有些字符会引起歧义。
对于 URL: &用于分割多个参数,倘若有某个参数键值为 name=v&lue,就会因为 name 参数的值 v&lue 中携带了&而造成歧义。因此需要对&进行 URL 编码。url编码后,服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。
对于 HTML: 当浏览器遇到会识别为元素的结束。倘若有” >,由于标签的属性值携带了>,同样会造成歧义。因此需要属性值的>需要 进行 HTML 编码,即使用字符实体。
二、三种编码
2.1HTML 编码(字符实体)
字符实体是一个预先定义好的转义序列。 字符实体两种表示方法:
1、 字符实体以&开头+预先定义的实体名称+;分号结束,如“
2、 字符实体还可以以&开头+#符号+字符在 ASCII 对应的十进制数字+;分号结束,如
字符都是有实体编号的,但有些字符是没有实体名称
显示结果 
描述
实体名称
实体编号
空格
 
 
小于号
<

大于号
>
>
&
和号
&
&

引号
"
"

撇号 
' (IE不支持)
'

分(cent)
¢
¢
£
镑(pound)
£
£
¥
元(yen)
¥
¥

欧元(euro)


§
小节
§
§
©
版权(copyright)
©
©
®
注册商标
®
®

商标


×
乘号
×
×
÷
除号
÷
÷
2.2 JavaScript 编码
最常用的,如\uXXXX 这种写法的Unicode 转义序列,表示一个字符,其中 XXXX 表示一个 16 进制数字,如
2.3 URL 编码
RFC3986 文档规定,URL 中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4 个特殊字 符以及所有保留字符。 RFC3986 中指定了以下字符为保留字符:! * ‘ ( ) ; : @ & = + $ , / ? # [ ]
编码方式 %加字符在 ASCII 码表中的十六进制值。例如,/在 ASCII 码表中十六进制为 0x2f,那么它对应的 URL 编码为%2f。
JavaScript 中提供了 3 个函数用来对 URL 编码以得到合法的 URL:
1、 escape()
2、 encodeURI()
3、 encodeURIComponent()
三、浏览器解码规则

浏览器无论什么情况都会遵守一个这样的解码规则:
1、 HTML 解析器对 HTML 文档进行解析,完成 HTML 解码并且创建 DOM 树
2、 JavaScript 或者 CSS 解析器对内联脚本进行解析,完成 JS、CSS 解码
3、 URL 解码会根据 URL 所在的顺序不同而在 JS 解码前或者解码后
3.1HTML 解析器
3.1.1HTML 中有五类元素:
1、 空元素(Voidelements),有 area、base、br、col、command、embed、hr、img、input、 keygen、link、meta、param、source、track、wbr
2、 原始文本元素(Raw textelements),有和
3、 RCDATA 元素(RCDATA elements),有和
4、 外部元素(Foreignelements),例如 MathML 命名空间或者 SVG 命名空间的元素
5、 基本元素(Normal elements),即除了以上 4 种元素以外的元素
五类元素的区别如下:
1、 空元素,不能容纳任何内容(因为它们没有闭合标签,没有内容能够放在开始标签和闭合标签中间)。
2、 原始文本元素,可以容纳文本。
3、 RCDATA 元素,可以容纳文本和字符引用。
4、 外部元素,可以容纳文本、字符引用、CDATA 段、其他元素和注释
5、 基本元素,可以容纳文本、字符引用、其他元素和注释
3.1.2 HTML编解码

HTML 解析器以状态机的方式运行,它从文档输入流中消耗字符并根据其转换规则转换到不同的状态。
示例:
   
    Hello world
   
   
1、 初始状态为”DataState”,当遇到””,每个字符都附加到这个符号名上,例子中创建的是一个 html 符号。
2、 当读取到”>”,当前的符号就完成了,此时,状态回到”Data state”,””重复这一处理过程。到这里,html 和 body 标签都识别出来了。现在,回到”Data state”,读取”Helloworld”中的字符”H”将创建并识别出一个字符符号,这里会为”Hello world”中的每个字符 生成一个字符符号。
3、 这样直到遇到””中的””。然后,产生一个新的标签符号并回到”Data state”。后面的””将和 “”一样处理。
总结:当HTML 解析器处于数据状态(DataState)、RCDATA 状态(RCDATA State)、属性值状态(Attribute Value State)时,字符实体会被解码为对应的字符。
示例:
<img src=x onerror=alert(4)>
被编码为字符实体<和>。 当 HTML 解析器解析完时,会进入数据状态(Data State)并发布标签令牌。接着解析到实体<时因为处在数据状态(Data State)就会对实体进行解码为。
这里会有个问题,被解码后,img是否会被解析为 HTML 标签而导致 JS 执行呢?
答案是否定的。因为解析器在使用字符引用后不会转换到标签打开状态(Tag OpenState),不进入标签打开状态就不会被发布为 HTML 标签。因此,不会创建新 HTML 标签, 只会将其作为数据来处理。 这也是为什么我们可以使用字符实体来避免用户不安全输入导致 XSS

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载