FastJSON反序列化时因setter返回父类类型被忽略导致字段为null,非安全漏洞而是解析逻辑失效;应将setter返回类型改为子类自身,或用@JSONField注解强制直设。

这个问题本质是反序列化框架(如 FastJSON)在处理链式调用风格的 Setter 时,因返回类型不匹配而跳过属性赋值,不是“读取漏洞”的安全问题,而是解析逻辑失效导致的数据丢失。关键不在迭代流,而在 setter 方法签名是否满足反序列化器的识别规则。
确认是否真由 Setter 重写引发
FastJSON 在反序列化时,会扫描类中所有 public 的 setter 方法(形如 setXxx(Type)),并根据方法名推断对应字段名(如 setX() → 字段 x)。它还会检查方法返回值:
- 若返回
void或 当前类自身类型(如Children setX(String x)),则正常调用并赋值; - 若返回父类类型(如
Parent setX(String x)),FastJSON 会认为该方法“不专属于当前类”,直接忽略,导致字段为null。
修复 Setter 方法签名
这是最直接、零副作用的解法。确保子类重写的每个 setter 都明确返回 子类自身类型:
- 错误写法(触发问题):
public Parent setX(String x) { this.x = x; return this; } - 正确写法(推荐):
public Children setX(String x) { this.x = x; return this; }
使用 Lombok 时,避免在子类上重复启用 @Accessors(chain = true) 后又手动重写 setter;若必须重写,请显式声明返回类型为子类。
避免依赖链式调用的反序列化路径
如果项目已大量存在返回父类类型的 setter,且无法统一修改,可绕过 setter 调用机制:
- 给目标字段添加
@JSONField(serialize = true, deserialize = true)注解,强制 FastJSON 使用反射直接设值; - 改用
JSON.parseObject(json, TypeReference)并配合Feature.SupportNonPublicField,让框架读取 private 字段(需字段非 final 且有对应 getter); - 临时方案:先解析为
JSONObject或Map<string object></string>,再手动构造对象——但失去类型安全和性能优势,不建议长期使用。
补充验证建议
不要仅凭日志或打印判断字段是否为空。应在反序列化后立即检查:
- 调用
JSON.toJSONString(obj)看输出是否含预期字段值; - 用调试器观察 FastJSON 内部
JavaBeanDeserializer是否将该 setter 加入setterInfo列表; - 对比不重写 setter 时的解析结果,确认差异点是否唯一对应被重写的那个方法。










