...
Code Block | ||||
---|---|---|---|---|
| ||||
import java.io.*; class OpenedFile implements Serializable { String filename; BufferedReader reader; public OpenedFile(String _filename) throws FileNotFoundException { filename = _filename; init(); } private void init() throws FileNotFoundException { reader = new BufferedReader(new FileReader(filename)); } private void writeObject(ObjectOutputStream out) throws IOException { out.writeUTF(filename); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { filename = in.readUTF(); init(); } } |
Compliant Solution
...
In this compliant solution, the readObject()
method throws an exception unless the deserialization is protected by a whitelist. Note that this compliant solution for SER13-J is complementary to the compliant solution in SER12-J. In the compliant solution for SER12-J, the source code location that invokes deserialization is modified to use a custom subclass of ObjectInputStream
. This subclass overrides the resolveClass()
method to check whether the class of the serialized object is whitelisted before that class's readObject()
method gets called. In contrast, in the following compliant solution, the presence of a whitelist is checked inside the readObject()
method of the dangerous serializable class. We do not need to verify that the whitelist actually contains the class, because if it did not, the readObject()
method would never get executed.
Code Block | ||||
---|---|---|---|---|
| ||||
import java.io.*; import java.lang.reflect.*; class OpenedFile implements Serializable { String filename; BufferedReader reader; public OpenedFile(String _filename) throws FileNotFoundException { filename = _filename; init(); } private void init() throws FileNotFoundException { reader = new BufferedReader(new FileReader(filename)); } private void writeObject(ObjectOutputStream out) throws IOException { out.writeUTF(filename); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { boolean hasWhitelist = false; try { in.getClass().getDeclaredField("whitelist"); hasWhitelist = true; } catch (ReflectiveOperationException e) {} if (!hasWhitelist) { throw new SecurityException("Deserialization without a whitelist is disallowed for class " + this.getClass().getName() + "."); } filename = in.readUTF(); init(); } } |
In this compliant solution, potentially dangerous operations are moved outside of deserialization, and user
Compliant Solution
...
In this compliant solution, potentially dangerous operations are moved outside of deserialization, and users of the class are required to make a separate call to init()
after deserializing.
...