It is often possible for Java code to deserialize data that comes from an untrusted source; however this is forbidden by rule SER12-J. Prevent deserialization of untrusted classes. A A Serializable
class can overload the
method, which is called when an object of that class is being deserialized. This method (as well as similar methods such as the method Serializable
.readObject()readResolve()
and readObjectNoData() ) should must treat the serialized data as potentially malicious . These methods should not perform and refrain from performing potentially dangerous operations, nor should they set the stage for such operations to be performed later in the deserialization process. unless the programmer has expressly indicated, for the particular deserialization at hand, that the class may perform potentially dangerous operations.
This rule complements rule SER12-J. Prevent deserialization of untrusted classes. Whereas SER12-J requires the programmer to validate data before deserializing it (to ensure the absence of classes that might perform dangerous operations when deserialized), SER13-J requires that all serializable classes refrain, by default, from performing dangerous operations during deserialization. SER12-J and SER13-J both guard against the same class of deserialization vulnerabilities. Theoretically, a given system is secure against this class of vulnerabilities if either (1) all deployed code on that system follows SER12-J or (2) all deployed code on that system follows SER13-J. However, since there is a lot of existing code that violates these rules, the CERT Coding Standard takes the "belt and suspenders" approach of requiring compliant code to follow both rules.
Non-Compliant Code Example
...
Code Block | ||||
---|---|---|---|---|
| ||||
import java.io.*; interface Whitelist { public boolean has(String className); } class WhitelistedObjectInputStream extends ObjectInputStream { Whitelist whitelist; public WhitelistedObjectInputStream(InputStream inputStream) throws IOException { super(inputStream); } public void setWhitelist(Whitelist wl) { whitelist = wl; } } class OpenedFile implements Serializable { public String filename; public BufferedReader reader; public OpenedFile(String _filename) { filename = _filename; init(); } private void init() { try { reader = new BufferedReader(new FileReader(filename)); } catch (FileNotFoundException e) { } } private void writeObject(ObjectOutputStream out) throws IOException { out.writeUTF(filename); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { ifboolean isWhitelisted = (!(in instanceof WhitelistedObjectInputStream) || && !((WhitelistedObjectInputStream) in).whitelist.has(this.getClass().getName())); if (!isWhitelisted) { throw new SecurityException("Attempted to deserialize unexpected class."); } filename = in.readUTF(); init(); } } |
...