Java反序列化安全合规问题:使用SealedObject能否有效防御RCE攻击?
不安全Java反序列化漏洞原理
Java原生反序列化过程中会自动调用待反序列化对象的readObject()、readResolve()等内置方法,攻击者可结合业务依赖中存在的可利用代码链(Gadget)构造恶意序列化数据包,服务端未做校验直接反序列化时就会触发恶意代码执行,也就是常说的RCE问题。直接接收客户端传入的序列化流并直接反序列化,相当于完全信任不可信的用户输入,自然存在被利用的风险。
SealedObject方案的局限性
单独使用SealedObject无法完全规避反序列化RCE风险。
SealedObject的核心作用是对序列化后的对象做加密封装,只有持有对应密钥的主体才能解密获取原始序列化数据,它解决的是「传输过程中序列化数据被第三方篡改、伪造」的问题,并没有从根源上消除反序列化风险:
- 如果加密密钥保存在客户端(当前场景agent部署在客户侧,密钥必然会下发到客户端),攻击者可以直接拿到合法密钥,自行构造恶意序列化对象加密后传给服务端,服务端解密后反序列化依然会触发RCE
- 就算密钥完全保存在服务端,解密后直接反序列化拿到的对象,依然存在被构造恶意内容的风险,本质上没有解决反序列化不可信数据的核心问题
推荐修复方案
- 优先替换序列化方案:大文件场景完全不需要使用Java原生序列化,可将业务元数据和文件二进制内容拆分传输,元数据用JSON、Protocol Buffers等无执行风险的序列化协议传输,文件内容直接走二进制分片上传,从根源上消除反序列化风险
- 如果必须保留Java原生序列化逻辑,必须增加严格的白名单校验:使用JDK提供的
ObjectInputFilter配置仅允许业务定义的指定类被反序列化,禁止所有其他类的反序列化权限,示例代码如下:
try (ObjectInputStream ois = new ObjectInputStream(inputStream)) { // 仅允许自定义的业务数据类反序列化,拒绝其他所有类 ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter("com.yourcompany.bigdata.UploadDataClass;!*")); UploadDataClass data = (UploadDataClass) ois.readObject(); }
- 若要结合SealedObject使用,需配合白名单+非对称加密逻辑:服务端保留私钥,给合法agent下发公钥,agent用公钥加密序列化数据,服务端用私钥解密后必须先经过白名单校验,再执行反序列化操作,可大幅提升攻击门槛。
内容的提问来源于stack exchange,提问作者Acciu
相关产品推荐
相关产品推荐

