Package google.registry.util
Class SafeObjectInputStream
java.lang.Object
java.io.InputStream
java.io.ObjectInputStream
google.registry.util.SafeObjectInputStream
- All Implemented Interfaces:
Closeable
,DataInput
,ObjectInput
,ObjectStreamConstants
,AutoCloseable
Safely deserializes Nomulus http request parameters.
Serialized Java objects may be passed between Nomulus components that hold different credentials. Deserialization of such objects should be protected against attacks through compromised accounts.
This class protects against three types of attacks by restricting the classes used for serialization:
- Remote code execution by referencing bad classes in compromised jars. When a class with
malicious code in the static initialization block or the deserialization code path (e.g.,
the
readObject
method) is deserialized, such code will be executed. For Nomulus, this risk comes from third-party dependencies. To counter this risk, this class only allows Nomulus (google.registry.**) classes and specific core Java classes, and forbid others including third-party dependencies. (As a side note, this class does not use allow lists for Nomulus or third-party classes because it is infeasible in practice. Super classes of the instance being deserialized must be resolved, and therefore must be on the allow list; same for the field types of the instance. The allow list for the JodaDateTime
class alone would have more than 10 classes. Generated classes, e.g., by AutoValue, present another problem: their real names are not meant to be a concern to the user). - CPU-targeting denial-of-service attacks. Containers and arrays may be used to construct
object graphs that require enormous amount of computation during deserialization and/or
during invocations of methods such as
hashCode
orequals
, taking minutes or even hours to complete. See here for an example of such object graphs. To counter this risk, this class forbids lists, maps, and arrays for deserialization. - Memory-targeting denial-of-service attacks. By forbidding container and arrays, this class
also prevents some memory-targeting attacks, e.g., using wire format that claims to be an
array of a huge size, causing the JVM to preallocate excessive amount of memory and
triggering the
OutOfMemoryError
. This is actually a small risk for Nomulus, since the impact of each error is limited to a single (spurious) request.
Nomulus classes with fields of array, container, or third-party Java types must implement
their own serialization/deserialization methods to be safely deserialized. For the common use
case of passing a collection of `safe` objects, SafeSerializationUtils.serializeCollection(java.util.Collection<?>)
and SafeSerializationUtils.safeDeserializeCollection(java.lang.Class<T>, byte[])
may be used.
-
Nested Class Summary
Nested classes/interfaces inherited from class java.io.ObjectInputStream
ObjectInputStream.GetField
-
Field Summary
Fields inherited from interface java.io.ObjectStreamConstants
baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, SC_BLOCK_DATA, SC_ENUM, SC_EXTERNALIZABLE, SC_SERIALIZABLE, SC_WRITE_METHOD, SERIAL_FILTER_PERMISSION, STREAM_MAGIC, STREAM_VERSION, SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION, TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS, TC_CLASSDESC, TC_ENDBLOCKDATA, TC_ENUM, TC_EXCEPTION, TC_LONGSTRING, TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE, TC_RESET, TC_STRING
-
Constructor Summary
-
Method Summary
Methods inherited from class java.io.ObjectInputStream
available, close, defaultReadObject, enableResolveObject, getObjectInputFilter, read, read, readBoolean, readByte, readChar, readClassDescriptor, readDouble, readFields, readFloat, readFully, readFully, readInt, readLine, readLong, readObject, readObjectOverride, readShort, readStreamHeader, readUnshared, readUnsignedByte, readUnsignedShort, readUTF, registerValidation, resolveObject, resolveProxyClass, setObjectInputFilter, skipBytes
Methods inherited from class java.io.InputStream
mark, markSupported, nullInputStream, read, readAllBytes, readNBytes, readNBytes, reset, skip, skipNBytes, transferTo
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface java.io.ObjectInput
read, skip
-
Constructor Details
-
SafeObjectInputStream
- Throws:
IOException
-
-
Method Details
-
resolveClass
- Overrides:
resolveClass
in classObjectInputStream
- Throws:
ClassNotFoundException
IOException
-