The problem is that the readObject method is effectively another public constructor, and it demands all of the same care as any other constructor. Just as a constructor must check its arguments for validity and make defensive copies of parameters where appropriate, so must a readObject method. If a readObject method fails to do either of these thing, it is a relatively simple matter for an attacker to violate the class's invariant.
Loosely speaking, readObject is a constructor that takes a byte stream as its solo parameter. In normal use, the byte stream is generated by serializing a normally constructed instance. The problem arises when readObject is presented with a byte stream that is artificially constructed to generate an object that voilates the invariant of its class.
private static Object deserialize(byte[] sf){
try{
InputStream is = new ByteArrayInputStream(sf);
ObjectInputStream ois = new ObjectInputStream(is);
return ois.readObject();
}catch(Exception e){
throw new IllegalArgumentException(e);
}
}
The byte array literal used to initialize serializedForm was generated by serializing a normal Period instance and hand-editing the resulting byte stream.
The serialization byte-stream format is described in the Java(TM) Object Serialization Specification.
While the Period instance is created with its invariants intact, it is possible to modify its internal components at will. Once is possession of a mutable Period instance, an attacker might cause great harm by passing the instance on to a class that depends on Period's immutability for its security. This is not so far-fetched: there are classes depend on String's immutability for their security.
When an object is deserialized, it's critical to defensively copy any field containing an object reference that a client must not possess.
Therefore, every serializable immutable class containing private mutable components must defensively copy these components in its readObject method.
A simple litmus test for decideing whether the default readObject method is acceptable for a class:
Would you feel comfortable adding a public constructor that took as parameters the values for each nontransient filed in the object and stored the values in the fields with no validation whatsoever?
分享到:
相关推荐
Item 88: Write readObject methods defensively Item 89: For instance control, prefer enum types to readResolve Item 90: Consider serialization proxies instead of serialized instances
本文将深入探讨如何使用JDBC进行数据读取,并结合"ReadObject Sink"的概念,这通常指的是从数据库读取对象并将其转换为Java对象的过程。 首先,让我们了解JDBC的基本概念。JDBC提供了一组接口和类,允许Java程序...
首先,`BinaryWriter`类提供了一系列方法,如`Write(int)`、`Write(double)`和`Write(string)`等,用于写入各种基本数据类型。然而,当我们需要保存自定义对象时,这些方法就不够用了。我们可以创建一个扩展方法,如...
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。 1.new方法显式调用构造方法; 2.反射方法无论是反射类还是反射构造方法都是通过构造方法构建对象; 3.通过对一个原有对象...
总之,Java对象的序列化可以通过`transient`关键字来排除某些字段,同时可以利用`writeObject()`和`readObject()`方法自定义序列化和反序列化的行为,以满足特定需求,例如处理`transient`字段的序列化,以及在网络...
序列化使用ObjectOutputStream的writeObject()方法,反序列化使用ObjectInputStream的readObject()方法。对象序列化在处理临时文件、网络通信或持久化存储中非常有用。 总之,Java的流式输入输出提供了处理输入输出...
java实验1-实现搜索引擎的倒排索引数据结构 实验1知识点: 集合类的使用如ArrayList,HashMap ◦对这些集合类的操作包括...具体使用方法,请见hust.cs.javacourse.search.util.FileUtils类的read方法和write方法 设计
write/readObject fast-fail subList iterator forEach sort removeIf Vector different with ArrayList 2018/3/26 ChangeLogs LinkedList ctor-2 addFirst addLast addAll add indexOf lastIndexOf peek 获取第一个...
- **实现`Serializable`接口并自定义序列化方法**:如果`Customer`类实现了`Serializable`接口,并定义了`writeObject`和`readObject`方法,那么序列化和反序列化操作将按照自定义的方法进行。 ```java public ...
修改了 ReadObject方法,经过测试.出于性能的考虑和使用的方便 内部采用了DataContractSerializer 序列化. bool ReadObject(out object obj) 变成了bool ReadObject(out T obj); 继承与FormatClassAttibutes的数据包...
kaishi = (游戏类) savewan1.readObject(); wan2 = (用户类) savewan2.readObject(); savewan1.close(); savewan2.close(); } catch (ClassNotFoundException e) { System.out.println("类型...
// other fields and methods } ``` 另外,`writeObject()`和`readObject()`方法可以重写,以自定义序列化和反序列化的行为。这些方法允许程序员控制哪些额外的数据或状态需要被保存和恢复。 `Test.java`, `Test1...
调用`readObject()`方法读取对象。 5. **字节流与打印流**: - **字节打印流的使用**:`java.io.FileOutputStream`与`java.io.PrintStream`结合,可以方便地向文件输出数据,如`PrintStream`的`print()`方法用于...
要读取对象,使用`ObjectInputStream`,如`ObjectInputStream in = new ObjectInputStream(new FileInputStream("file.dat"))`,然后通过`readObject()`方法读取。但是,要序列化对象,该对象必须实现`Serializable`...
public void readObject(ObjectInputStream in) { try { id = in.readInt(); roleName = in.readUTF(); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 2. User类的设计 同样地,在`User`...
1. 实现`Serializable`接口但不定义`readObject`和`writeObject`方法:在这种情况下,JDK会默认处理对象的序列化和反序列化,将对象的非`transient`和非`static`字段转换成字节流。这是最简单的方法,适用于大多数...
CArchive的 和>> 操作符用于简单数据类型的读写,对于CObject派生类的对象的存取要使用ReadObject()和WriteObject()。使用CArchive的ReadClass()和WriteClass()还可以进行类的读写,如: //存储CAboutDlg类 ...
例如,可以通过`ObjectOutputStream`的`writeObject`方法将对象写入字节数组,然后通过`ObjectInputStream`的`readObject`方法从字节数组中读取对象。 #### 小结 本文档主要介绍了Java中序列化的基本概念和实现...