Gson参数走私漏洞分析与防御指南
0x00 Gson简介
Gson是Google开发的一个Java库,用于Java对象与JSON格式数据之间的序列化和反序列化。它以简单易用和高性能著称,广泛应用于Java生态系统中。
0x01 Gson解析过程详解
基本解析流程
-
初始化解析:
Gson gson = new Gson(); User user = gson.fromJson(body, User.class); -
解析路径:
- 最终调用
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
String body = "{\"activityId\":\"123\",\"activityId\":\"321\"}"; // 会抛出异常 - 对重复键值做校验,抛出
空白字符处理差异
-
Gson与Fastjson对比:
- Gson允许的无意义字符:
\n、空格、\t、\r - Fastjson额外处理:
\b、\f
- Gson允许的无意义字符:
-
关键差异点:
- 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数据时的安全性。\]