运行时依赖
安装命令
点击复制技能文档
Jackson 反序列化安全关键概念:反序列化时序 Jackson 在单个 readValue() 调用期间将 JSON 文本转换为 Java 对象。这种转换不是简单的数据复制——Jackson 解释 JSON 结构,解析类型,处理特殊键,并实例化对象,所有这些都在此操作中完成。 JSON 字符串 → [Jackson 处理] → Java 对象 ↑ 攻击面在这里 一旦反序列化完成,所得到的 Java 对象中不再包含其构造方式的任何痕迹。任何特殊的 JSON 结构、不寻常的键或类型指令在对象创建过程中都不会再可见。
为什么反序列化后验证不足 考虑一个典型的 JSON 端点的生命周期:
- HTTP 请求带有 JSON 正文到达
- 框架反序列化 JSON → Java 对象(Jackson 在此运行)
- 你的代码接收 Java 对象
- 你的代码验证对象
- 你的代码处理对象
空键("")攻击向量 什么是它? JSON 允许空字符串作为对象键:{ "name": "合法", "": "注入值" } 这是有效的 JSON,符合 RFC 8259。Jackson 无错误地解析它。
为什么它很重要? 一些应用程序和框架为空键赋予特殊含义: 注入点:某些 Jackson 配置使用 "" 来设置根对象的值或触发特殊处理 属性覆盖:空键可能与 @JsonAnySetter 或自定义反序列化器交互 框架行为:一些框架将 "" 解释为“应用于父级”或“默认目标” 可见性问题 在反序列化后,没有标准的方法可以知道空键存在: // 原始 JSON:{"name": "test", "": "恶意"} MyObject obj = mapper.readValue(json, MyObject.class); // obj.getName() 返回 "test" // "" 到哪里去了?取决于配置。你不能从 obj 中看出。
其他结构攻击模式 多态类型处理 当 Jackson 配置了 @JsonTypeInfo 时,JSON 可以指定要实例化的类:{ "@class": "com.attacker.MaliciousClass", "command": "rm -rf /" } Jackson 将尝试实例化指定的类。如果类路径包含可利用的“小工具”类,可能会在反序列化期间发生任意代码执行——在你的代码运行之前。所得到的对象可能是预期类型(如果攻击类是子类型),或者反序列化可能在造成损害之前部分成功。
重复键 JSON 不禁止重复键。Jackson 的默认行为:最后一个值获胜。 { "role": "user", "role": "admin" } Jackson 生成一个 role 等于 "admin" 的对象。如果上游验证(如 WAF 或输入过滤器)仅检查第一次出现,而 Jackson 使用最后一个,则验证和处理看到的值不同。
嵌套注入 深度嵌套的结构可以绕过深度限制验证: { "config": { "settings": { "internal": { "": "payload" } } } } 简单的字符串检查可能会错过嵌套结构中埋藏的模式。