阅读Instant
类的源代码时,我遇到了这个方法
/**
* Defend against malicious streams.
*
* @param s the stream to read
* @throws InvalidObjectException always
*/
private void readObject(ObjectInputStream s) throws InvalidObjectException {
throw new InvalidObjectException("Deserialization via serialization delegate");
}
这个描述让我很好奇。什么是"恶意流"?这种方法是如何防御的?
Instant
和其他java.time
类使用包范围的委托java.time.Ser
进行序列化。请参见writeReplace
方法以查看如何创建委托。
因此,调用readObject
方法的唯一方法是,如果有人传入恶意流(创建恶意流的唯一目的是试图创建无效对象)。该异常可确保阻止此类恶意流。
通常,任何时候使用序列化委托时,都应该考虑像这样阻塞readObject
。
《高效Java》的作者Joshua Bloch介绍了他关于序列化代理模式的想法。你的问题背景很有启发性。
有了这个writeReplace方法,序列化系统将永远不要生成封闭类的序列化实例,而是攻击者可能会伪造一个以试图违反类不变量。为了保证这样的攻击会失败,只需添加以下内容到封闭类的readObject方法。。。
// readObject method for the serialization proxy pattern
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Proxy required");
}