浏览器解码看XSS
字数 1607 2025-08-26 22:11:57

浏览器解码机制与XSS攻击防御详解

浏览器解码规则概述

浏览器在处理网页内容时遵循严格的解码顺序:

  1. HTML解析器对HTML文档进行解析,完成HTML解码并创建DOM树
  2. JavaScript或CSS解析器对内联脚本进行解析,完成JS/CSS解码
  3. URL解码根据URL所在顺序不同,可能在JS解码前或解码后进行

HTML编解码机制

HTML解析器工作原理

HTML解析器作为状态机,从输入流获取字符并按规则转换状态。遇到<符号(后面没有/)会进入"标签开始状态",经过一系列状态转换后进入"数据状态"并释放当前标签的token。

HTML元素分为五类:

  1. 空元素(Void elements):如<area>, <br>, <base>等,不能容纳内容
  2. 原始文本元素(Raw text elements)<script><style>
  3. RCDATA元素(RCDATA elements)<textarea><title>
  4. 外部元素(Foreign elements):如MathML或SVG命名空间的元素
  5. 基本元素(Normal elements):除以上4种外的其他元素

HTML解码关键点

  • 在"数据状态(Data state)"下进行HTML编码
  • 示例:
    • <&#104;1>hhhhh</h1> 无法解析
    • <h1>hhhhhhhh&#104</h1> 能正确解析
  • RCDATA元素(<textarea><title>)中的字符引用会被HTML解析器解码
  • 在RCDATA元素中,只有</textarea></title>会被识别为标签

SVG元素的特殊性

<svg>遵循XML和SVG定义规则:

  • 在XML中,&#40;会被解析成(
  • XML中实体会自动转义,除了<![CDATA[]]>包含的实体

JavaScript编解码机制

JS编码规则

  • 对除阿拉伯数字和字母外的所有内容进行编码
  • 常用Unicode转义序列如\uXXXX(如<的Unicode编码为\u003c

JS解码关键点

  1. 单引号、双引号和圆括号等控制字符编码后将无法识别

    • 错误示例:``
    • 正确示例:``
  2. 编码顺序影响:

    • 先JS编码再HTML解码:
      
      
      浏览器:HTML解码 → JS解码 → 执行
  3. 开发中的常见漏洞:

    • 仅使用HTML实体编码防御XSS不足
    • 示例漏洞:
      
      
    • 攻击者可输入:");alert("test 然后HTML编码绕过

正确防御方法

应先进行JavaScript编码,再进行HTML编码:

  1. 服务器看到的内容应为JS编码后的形式
  2. HTML解码后变为JS编码形式
  3. JavaScript解析器工作时,控制字符仅被解析为标识符名称或字符串

URL编解码机制

URL解码顺序示例

<a href="javascript:alert(3)">hhhhh<a>

浏览器处理顺序:

  1. 看到<标签 → HTML解码
  2. 看到href → URL解码
  3. 看到javascript → JS解码

攻击编码步骤

  1. 先进行JS编码:
    <a href="javascript:\u0061\u006c\u0065\u0072\u0074(3)">hhhhhh</a>
    
  2. 再进行URL编码:
    <a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(3)">hhhhhh</a>
    
  3. 最后进行HTML编码

复杂场景示例

<a onclick="window.open('value1')" href="javascript:window.open(value2)">
  • value1处理顺序:

    1. HTML解码
    2. JS解码
    3. URL解码
  • value2处理顺序:

    1. HTML解码
    2. URL解码
    3. JS解码
    4. URL解码

总结与防御建议

  1. 理解浏览器解码机制是XSS攻击和防御的基础

  2. 不同上下文需要采用不同的编码策略

  3. 单一编码方式无法全面防御XSS

  4. 推荐防御策略:

    • 在HTML上下文中:先JS编码,再HTML编码
    • 在URL上下文中:注意解码顺序,采用多层编码
    • 在JS上下文中:严格控制输入,使用专用编码函数
  5. 开发注意事项:

    • 不要仅依赖HTML实体编码
    • 根据输入点的上下文选择合适的编码方式
    • 测试各种编码组合的解析结果

参考资料

  1. HTML-Javscript-self-decode
  2. 浏览器解析机制
  3. XSS防御指南
  4. 师傅的总结
浏览器解码机制与XSS攻击防御详解 浏览器解码规则概述 浏览器在处理网页内容时遵循严格的解码顺序: HTML解析器 对HTML文档进行解析,完成HTML解码并创建DOM树 JavaScript或CSS解析器 对内联脚本进行解析,完成JS/CSS解码 URL解码 根据URL所在顺序不同,可能在JS解码前或解码后进行 HTML编解码机制 HTML解析器工作原理 HTML解析器作为状态机,从输入流获取字符并按规则转换状态。遇到 < 符号(后面没有 / )会进入"标签开始状态",经过一系列状态转换后进入"数据状态"并释放当前标签的token。 HTML元素分为五类: 空元素(Void elements) :如 <area> , <br> , <base> 等,不能容纳内容 原始文本元素(Raw text elements) : <script> 和 <style> RCDATA元素(RCDATA elements) : <textarea> 和 <title> 外部元素(Foreign elements) :如MathML或SVG命名空间的元素 基本元素(Normal elements) :除以上4种外的其他元素 HTML解码关键点 在"数据状态(Data state)"下进行HTML编码 示例: <&#104;1>hhhhh</h1> 无法解析 <h1>hhhhhhhh&#104</h1> 能正确解析 RCDATA元素( <textarea> 和 <title> )中的字符引用会被HTML解析器解码 在RCDATA元素中,只有 </textarea> 或 </title> 会被识别为标签 SVG元素的特殊性 <svg> 遵循XML和SVG定义规则: 在XML中, &#40; 会被解析成 ( XML中实体会自动转义,除了 <![CDATA[ 和 ]]> 包含的实体 JavaScript编解码机制 JS编码规则 对除阿拉伯数字和字母外的所有内容进行编码 常用Unicode转义序列如 \uXXXX (如 < 的Unicode编码为 \u003c ) JS解码关键点 单引号、双引号和圆括号等控制字符编码后将无法识别 错误示例: `` 正确示例: `` 编码顺序影响: 先JS编码再HTML解码: 浏览器:HTML解码 → JS解码 → 执行 开发中的常见漏洞: 仅使用HTML实体编码防御XSS不足 示例漏洞: 攻击者可输入: ");alert("test 然后HTML编码绕过 正确防御方法 应先进行JavaScript编码,再进行HTML编码: 服务器看到的内容应为JS编码后的形式 HTML解码后变为JS编码形式 JavaScript解析器工作时,控制字符仅被解析为标识符名称或字符串 URL编解码机制 URL解码顺序示例 浏览器处理顺序: 看到 < 标签 → HTML解码 看到 href → URL解码 看到 javascript → JS解码 攻击编码步骤 先进行JS编码: 再进行URL编码: 最后进行HTML编码 复杂场景示例 value1 处理顺序: HTML解码 JS解码 URL解码 value2 处理顺序: HTML解码 URL解码 JS解码 URL解码 总结与防御建议 理解浏览器解码机制是XSS攻击和防御的基础 不同上下文需要采用不同的编码策略 单一编码方式无法全面防御XSS 推荐防御策略: 在HTML上下文中:先JS编码,再HTML编码 在URL上下文中:注意解码顺序,采用多层编码 在JS上下文中:严格控制输入,使用专用编码函数 开发注意事项: 不要仅依赖HTML实体编码 根据输入点的上下文选择合适的编码方式 测试各种编码组合的解析结果 参考资料 HTML-Javscript-self-decode 浏览器解析机制 XSS防御指南 师傅的总结