Jayway JsonPath参数走私导致的权限绕过
字数 1505 2025-08-19 12:42:11

Jayway JsonPath参数走私导致的权限绕过分析

0x00 前言

本文详细分析由于JSON解析器差异导致的参数走私和权限绕过问题,重点探讨Jayway JsonPath与Jackson解析器的不同行为。

0x01 背景知识

JSON解析器差异

  1. Fastjson与Jackson的差异

    • Fastjson反序列化时对大小写不敏感
    • Jackson默认大小写敏感(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES默认false)
    • 两者对重复键的处理:默认保留最后一个键值对
  2. Spring Boot默认配置

    • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES默认关闭
    • 通过JacksonAutoConfiguration类配置
    • 使用Jackson2ObjectMapperBuilder创建ObjectMapper

0x02 Jayway JsonPath解析分析

1.1 JsonSmartJsonProvider解析流程

  1. 入口点

    • com.jayway.jsonpath.spi.json.JsonSmartJsonProvider#parse
    • 最终调用net.minidev.json.parser.JSONParserBase#parse
  2. 解析过程

    • 读取第一个字符,准备开始解析
    • 调用readFirst方法开始解析
    • 处理空白字符(空格、制表符、换行符等)
  3. 对象解析

    • 遇到{字符时调用readObject(mapper)
    • 检查解析深度(默认限制400)
    • 循环读取键值对
  4. 键值处理

    • 引号处理:双引号或单引号
    • 非引号字符串使用readNQString(stopKey)
    • 包含转义字符\时调用readString2
  5. 特殊字符处理

    • ASCII控制字符(\u0000\u001f)默认抛出异常
    • \u007F(删除控制字符)会被跳过处理
  6. 值设置

    • 使用Map维护键值对
    • 重复键值保留最后一个

1.2 与Jackson的解析差异

  1. 控制字符处理

    • Jackson的ALLOW_UNESCAPED_CONTROL_CHARS默认false
    • 遇到未转义控制字符会抛出异常
  2. \u007F处理

    • JsonSmartJsonProvider会跳过
    • Jackson会正常处理

0x03 绕过技术分析

构造恶意请求

  1. 利用Unicode转义

    {
      "activit\\u0079Id": 1,
      "activit\\u0079Id\u007F": 3
    }
    
  2. 解析结果差异

    • JsonSmartJsonProvider解析:
      • \u0079解码为y
      • 跳过\u007F
      • 最终读取activityId值为3
    • Jackson解析:
      • \u0079解码为y
      • 保留\u007F
      • 最终读取activityId值为1

实际攻击场景

  1. 攻击流程

    • 第一个参数设置他人资源ID
    • 第二个参数(含\u007F)设置当前用户资源ID
    • 前端校验通过他人ID
    • 后端处理使用当前用户ID
  2. 代码示例

    String body = "{\"activit\\u0079Id\":1,\"activit\\u0079Id\u007F\":3}";
    
    // Jackson解析
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    User user = objectMapper.readValue(body, User.class);
    System.out.println("jackson parse result:" + user.getActivityId()); // 输出1
    
    // JsonSmartJsonProvider解析
    DocumentContext context = JsonPath.parse(body);
    System.out.println("JsonSmartJsonProvider parse result:" + 
      (String)context.read("$.activityId", String.class, new Predicate[0])); // 输出3
    

0x04 防御措施

  1. 统一解析器

    • 配置JsonPath使用Jackson解析器:
      Configuration.setDefaults(new Configuration.Defaults() {
          private final JsonProvider jsonProvider = new JacksonJsonProvider();
          private final MappingProvider mappingProvider = new JacksonMappingProvider();
      
          @Override
          public JsonProvider jsonProvider() {
              return jsonProvider;
          }
      
          @Override
          public MappingProvider mappingProvider() {
              return mappingProvider;
          }
      
          @Override
          public Set<Option> options() {
              return EnumSet.noneOf(Option.class);
          }
      });
      
  2. 输入验证

    • 过滤控制字符
    • 验证参数格式和内容
  3. 安全配置

    • 启用FAIL_ON_UNKNOWN_PROPERTIES
    • 配置严格的JSON解析选项

0x05 总结

本文详细分析了由于Jayway JsonPath与Jackson解析器差异导致的参数走私问题,重点介绍了利用Unicode控制字符实现的权限绕过技术。防御的关键在于保持JSON解析模式的一致性,并实施严格的输入验证。

Jayway JsonPath参数走私导致的权限绕过分析 0x00 前言 本文详细分析由于JSON解析器差异导致的参数走私和权限绕过问题,重点探讨Jayway JsonPath与Jackson解析器的不同行为。 0x01 背景知识 JSON解析器差异 Fastjson与Jackson的差异 : Fastjson反序列化时对大小写不敏感 Jackson默认大小写敏感( MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES 默认false) 两者对重复键的处理:默认保留最后一个键值对 Spring Boot默认配置 : DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 默认关闭 通过 JacksonAutoConfiguration 类配置 使用 Jackson2ObjectMapperBuilder 创建 ObjectMapper 0x02 Jayway JsonPath解析分析 1.1 JsonSmartJsonProvider解析流程 入口点 : com.jayway.jsonpath.spi.json.JsonSmartJsonProvider#parse 最终调用 net.minidev.json.parser.JSONParserBase#parse 解析过程 : 读取第一个字符,准备开始解析 调用 readFirst 方法开始解析 处理空白字符(空格、制表符、换行符等) 对象解析 : 遇到 { 字符时调用 readObject(mapper) 检查解析深度(默认限制400) 循环读取键值对 键值处理 : 引号处理:双引号或单引号 非引号字符串使用 readNQString(stopKey) 包含转义字符 \ 时调用 readString2 特殊字符处理 : ASCII控制字符( \u0000 到 \u001f )默认抛出异常 \u007F (删除控制字符)会被跳过处理 值设置 : 使用Map维护键值对 重复键值保留最后一个 1.2 与Jackson的解析差异 控制字符处理 : Jackson的 ALLOW_UNESCAPED_CONTROL_CHARS 默认false 遇到未转义控制字符会抛出异常 \u007F 处理 : JsonSmartJsonProvider会跳过 Jackson会正常处理 0x03 绕过技术分析 构造恶意请求 利用Unicode转义 : 解析结果差异 : JsonSmartJsonProvider解析: 将 \u0079 解码为 y 跳过 \u007F 最终读取 activityId 值为3 Jackson解析: 将 \u0079 解码为 y 保留 \u007F 最终读取 activityId 值为1 实际攻击场景 攻击流程 : 第一个参数设置他人资源ID 第二个参数(含 \u007F )设置当前用户资源ID 前端校验通过他人ID 后端处理使用当前用户ID 代码示例 : 0x04 防御措施 统一解析器 : 配置JsonPath使用Jackson解析器: 输入验证 : 过滤控制字符 验证参数格式和内容 安全配置 : 启用 FAIL_ON_UNKNOWN_PROPERTIES 配置严格的JSON解析选项 0x05 总结 本文详细分析了由于Jayway JsonPath与Jackson解析器差异导致的参数走私问题,重点介绍了利用Unicode控制字符实现的权限绕过技术。防御的关键在于保持JSON解析模式的一致性,并实施严格的输入验证。