gson参数走私浅析
字数 1786 2025-08-20 18:18:10

Gson参数走私漏洞分析与防御指南

0x00 Gson简介

Gson是Google开发的一个Java库,用于Java对象与JSON格式数据之间的序列化和反序列化。它以简单易用和高性能著称,广泛应用于Java生态系统中。

0x01 Gson解析过程详解

基本解析流程

  1. 初始化解析

    Gson gson = new Gson();
    User user = gson.fromJson(body, User.class);
    
  2. 解析路径

    • 最终调用fromJson(JsonReader reader, Type typeOfT)方法
    • peek()方法中调用doPeek处理有效元素
  3. 空白字符处理

    • 通过nextNonWhitespace方法跳过JSON流中的空白字符
    • 允许的无意义字符包括:\n、空格、\t\r
  4. 注释处理

    • 支持三种注释格式:
      • /**/(多行注释)
      • //(单行注释)
      • #(单行注释)
  5. 适配器选择

    • 获取合适的自定义Adapter或Gson自带Adapter
    • 调用对应的read方法进行JSON解析

TypeAdapter机制

  1. TypeAdapter作用

    • 接管特定类型的序列化和反序列化过程
    • 主要方法:
      • write(JsonWriter,T) - 序列化
      • read(JsonReader) - 反序列化
  2. 常见TypeAdapterFactory

    • MapTypeAdapterFactory:解析map类型数据
    • ReflectiveTypeAdapterFactory:处理自定义对象(如User类)

ReflectiveTypeAdapterFactory解析细节

  1. 对象创建

    • 使用this.constructor.construct()创建新实例
  2. 字段处理

    • in.beginObject()标记JSON对象开始
    • 循环遍历所有字段:
      • in.nextName()获取字段名
      • boundFields集合获取对应的BoundField对象
      • 如果字段标记为deserialized,则调用field.read(in, instance)
      • 否则调用in.skipValue()跳过字段
    • in.endObject()标记JSON对象结束
  3. 键名解析

    • 支持三种格式:
      • 单引号(')
      • 双引号(")
      • 无引号
  4. 值解析

    • 通过nextString方法处理
    • 同样支持三种格式:单引号、双引号、无引号
    • 特殊处理如Long.toString

0x02 参数走私漏洞分析

重复键值处理差异

  1. ReflectiveTypeAdapterFactory

    • 默认取重复键值的后者(新值覆盖旧值)
  2. MapTypeAdapterFactory

    • 对重复键值做校验,抛出JsonSyntaxException
    String body = "{\"activityId\":\"123\",\"activityId\":\"321\"}";
    // 会抛出异常
    

空白字符处理差异

  1. Gson与Fastjson对比

    • Gson允许的无意义字符:\n、空格、\t\r
    • Fastjson额外处理:\b\f
  2. 关键差异点

    • Gson允许key/value首字母不带引号
    • 特殊字符出现在value第一个字符时,Gson会将其作为键的一部分
    String body = "{
    

\[\"activityId\":\"123\"}"; // Gson会正常解析,$作为键的一部分 ``` ### 实际攻击案例 1. **案例1:利用\b字符**: ```java String body = "{\"activityId\":\"123\",\b\"activityId\":\"321\"}"; ``` - Gson:将`\b"activityId"`视为独立键,取前者("123") - Fastjson:忽略`\b`,取后者("321") 2. **案例2:利用分号**: ```java String body = "{\"activityId\":\"123\";\"activityId\":\"321\"}"; ``` - Gson:将`;`视为分隔符,取后者("321") - Fastjson:错误解析,取前者("123") 3. **案例3:利用注释符**: - Gson支持`/**/`、`//`、`#`三种注释 - 可与不敏感解析器结合造成参数走私 ## 0x03 防御措施 1. **输入验证**: - 严格校验JSON格式,禁止重复键 - 过滤特殊字符(`\b`、`\f`、`;`等) 2. **解析器配置**: - 使用严格模式解析JSON - 禁用注释支持(如有相关配置) 3. **一致性处理**: - 系统内统一使用同一种JSON解析器 - 前后端使用相同的解析逻辑 4. **安全更新**: - 及时更新Gson到最新版本 - 关注安全公告和补丁 5. **自定义TypeAdapter**: - 实现严格的键值处理逻辑 - 对异常格式进行拒绝而非尝试解析 ## 0x04 总结 Gson作为广泛使用的JSON解析库,其灵活的解析特性在某些场景下可能导致参数走私风险。开发者需要充分了解解析差异,实施严格的输入验证和安全配置,确保系统在处理JSON数据时的安全性。\]

Gson参数走私漏洞分析与防御指南 0x00 Gson简介 Gson是Google开发的一个Java库,用于Java对象与JSON格式数据之间的序列化和反序列化。它以简单易用和高性能著称,广泛应用于Java生态系统中。 0x01 Gson解析过程详解 基本解析流程 初始化解析 : 解析路径 : 最终调用 fromJson(JsonReader reader, Type typeOfT) 方法 在 peek() 方法中调用 doPeek 处理有效元素 空白字符处理 : 通过 nextNonWhitespace 方法跳过JSON流中的空白字符 允许的无意义字符包括: \n 、空格、 \t 、 \r 注释处理 : 支持三种注释格式: /**/ (多行注释) // (单行注释) # (单行注释) 适配器选择 : 获取合适的自定义Adapter或Gson自带Adapter 调用对应的 read 方法进行JSON解析 TypeAdapter机制 TypeAdapter作用 : 接管特定类型的序列化和反序列化过程 主要方法: write(JsonWriter,T) - 序列化 read(JsonReader) - 反序列化 常见TypeAdapterFactory : MapTypeAdapterFactory :解析map类型数据 ReflectiveTypeAdapterFactory :处理自定义对象(如User类) ReflectiveTypeAdapterFactory解析细节 对象创建 : 使用 this.constructor.construct() 创建新实例 字段处理 : in.beginObject() 标记JSON对象开始 循环遍历所有字段: in.nextName() 获取字段名 从 boundFields 集合获取对应的 BoundField 对象 如果字段标记为 deserialized ,则调用 field.read(in, instance) 否则调用 in.skipValue() 跳过字段 in.endObject() 标记JSON对象结束 键名解析 : 支持三种格式: 单引号( ' ) 双引号( " ) 无引号 值解析 : 通过 nextString 方法处理 同样支持三种格式:单引号、双引号、无引号 特殊处理如 Long.toString 0x02 参数走私漏洞分析 重复键值处理差异 ReflectiveTypeAdapterFactory : 默认取重复键值的后者(新值覆盖旧值) MapTypeAdapterFactory : 对重复键值做校验,抛出 JsonSyntaxException 空白字符处理差异 Gson与Fastjson对比 : Gson允许的无意义字符: \n 、空格、 \t 、 \r Fastjson额外处理: \b 、 \f 关键差异点 : Gson允许key/value首字母不带引号 特殊字符出现在value第一个字符时,Gson会将其作为键的一部分 实际攻击案例 案例1:利用\b字符 : Gson:将 \b"activityId" 视为独立键,取前者("123") Fastjson:忽略 \b ,取后者("321") 案例2:利用分号 : Gson:将 ; 视为分隔符,取后者("321") Fastjson:错误解析,取前者("123") 案例3:利用注释符 : Gson支持 /**/ 、 // 、 # 三种注释 可与不敏感解析器结合造成参数走私 0x03 防御措施 输入验证 : 严格校验JSON格式,禁止重复键 过滤特殊字符( \b 、 \f 、 ; 等) 解析器配置 : 使用严格模式解析JSON 禁用注释支持(如有相关配置) 一致性处理 : 系统内统一使用同一种JSON解析器 前后端使用相同的解析逻辑 安全更新 : 及时更新Gson到最新版本 关注安全公告和补丁 自定义TypeAdapter : 实现严格的键值处理逻辑 对异常格式进行拒绝而非尝试解析 0x04 总结 Gson作为广泛使用的JSON解析库,其灵活的解析特性在某些场景下可能导致参数走私风险。开发者需要充分了解解析差异,实施严格的输入验证和安全配置,确保系统在处理JSON数据时的安全性。