如何解决Checkmarx扫描检出的不可信数据反序列化高危问题
不可信数据反序列化高危缺陷修复方案
你贴出的代码使用Java原生ObjectInputStream做反序列化时,没有任何类型校验逻辑,攻击者可以构造恶意序列化数据,在反序列化过程中触发恶意代码执行,属于最高危的远程代码执行(RCE)风险,这是Checkmarx报高危缺陷的核心原因。
修复方案
方案1:替换原生序列化机制(优先推荐)
- 彻底放弃Java原生序列化逻辑,改用JSON、Protocol Buffers、XML等结构化数据格式做数据持久化/传输,配套使用Jackson、Protobuf、JAXB等序列化库,这类库默认只会反序列化指定类型的对象,不会触发任意未知类的构造逻辑,从根源避免反序列化漏洞。
方案2:自定义安全ObjectInputStream(兼容历史逻辑时使用)
如果业务必须保留原生序列化逻辑,需要自定义带白名单校验的ObjectInputStream子类,重写resolveClass方法限制只允许反序列化业务需要的类,示例代码如下:
public class SafeObjectInputStream extends ObjectInputStream { // 白名单:仅允许反序列化的业务类,按需添加 private static final Set<String> ALLOWED_CLASSES = new HashSet<>(Arrays.asList( "com.xxx.YourBusinessClass", "java.lang.String" )); public SafeObjectInputStream(InputStream in) throws IOException { super(in); } @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { if (!ALLOWED_CLASSES.contains(desc.getName())) { throw new InvalidClassException("Unauthorized deserialization attempt: " + desc.getName()); } return super.resolveClass(desc); } }
替换原有代码的ObjectInputStream,同时推荐使用try-with-resources自动关流,避免原代码的资源泄漏风险:
File file = new File(path); try (FileInputStream fin = new FileInputStream(file); SafeObjectInputStream ois = new SafeObjectInputStream(fin)) { Object result = ois.readObject(); // 后续业务逻辑 }
方案3:使用成熟工具类加固
可以直接使用Apache Commons IO内置的ValidatingObjectInputStream,无需自己封装校验逻辑:
try (FileInputStream fin = new FileInputStream(path); ValidatingObjectInputStream ois = new ValidatingObjectInputStream(fin)) { // 添加允许反序列化的类到白名单 ois.accept(YourBusinessClass.class, String.class); Object result = ois.readObject(); }
额外加固建议
- 反序列化前先校验数据完整性:提前校验序列化文件的哈希值、数字签名,确认数据未被篡改,避免恶意数据流进入反序列化逻辑
- 最小权限原则:运行反序列化逻辑的进程不要分配多余系统权限,降低漏洞被利用后的损失
- 严格管控数据源:如果反序列化的文件是用户可上传/修改的,必须做严格的权限校验,禁止未授权用户修改序列化文件
内容的提问来源于stack exchange,提问作者user3291914
相关产品推荐
相关产品推荐

