3 ms·
So it's not a Java bug, it's an Apache Commons-Collection bug. Granted, it's an extremely popular library, but it's not a "Java" bug.
by CountHackulus 11y ago
So it's not a Java bug, it's an Apache Commons-Collection bug. Granted, it's an extremely popular library, but it's not a "Java" bug.
- kevinherron 11y agoIt's not a commons-collections bug. There is nothing wrong with the existence of the classes being used from the commons-collections on their own. In fact, I'm sure they serve a purpose. But, in an application that deserializes objects from an untrusted source, the fact that they happen to be on the class path leads to them being available to use in an undesirable manner.
- pron 11y agoI agree. It is an ObjectInputStream security hole which needs to be patched by having it execute readResolve/readObject(ObjectInputStream) under a different security context.
- matt_heimer 11y agoThe native execution bug is in the Apache Commons code but the serialization issue is an attack vector that can be exploited if you are too lazy to implement some form of white listing. Think about class loading. Does your JVM/classloader implement class unloading? How much memory can I use in your JVM in I cause every single class on your CLASSPATH to load into memory? It would have been nice if ObjectInputStream was abstract and required a subclass that provided a whitelist of classes.
- barrkel 11y agoOr even a simple predicate.
- skybrian 11y agoThe bug is that doing deserialization safely is difficult in the presence of inheritance, since it's an open-world type system. If a serializable object contains a field of type Foo, this implies that all subtypes of Foo can be transmitted, whether they were designed with serialization in mind or not. This is especially bad for commonly used base types such as List or Exception. At the limit, if you have a field of type Object or Any, there's no choice but to use an explicit whitelist. Contrast with how Go does unmarshaling in its standard library (which works with structs and arrays but not interfaces), and functional languages (which use unions in the form of algebraic data types, not inheritance). These are closed-world type systems where we can generate the whitelist by walking the type tree from the base type.
- hyperpallium 11y agoRestricting serialization to JSON-like objects loses the benefit of being able to "serialize objects". (However, having that separate internal format for data may well be a better way to go, in general.) The algebraic approach, in this context, is similar to a superclass naming its subclasses (rather than a subclass naming its superclasses as java does). I'm not sure, but I suspect this open-world choice is deliberate, allowing extensibility. Java is very attentive to security considerations elsewhere. It also would be a too-dramatic change for mainstream OO programming languages. A third approach is explicitly closed-world: naming the set of classes permitted for deserialization, as per some other commenters. e.g. JAXB does this by necessity, for binding to XML Schema's algebraic type system.
- pron 11y ago> naming the set of classes permitted for deserialization Or simply having ObjectInputStream execute readResolve/readObject(ObjectInputStream) under a different security context. No need for whitelisting.
- pron 11y ago> The bug is that doing deserialization safely is difficult in the presence of inheritance, since it's an open-world type system. Well, yes and no. Java's open-world type system is one of its greatest features. To counteract any security holes this may cause, Java has a very strong security model, where each piece of executable code is associated with a security context based on its origin, and what it is allowed to do is restricted by a security policy based on the code's domain. In this case, however, no foreign code was directly introduced. It was found to be possible to exploit code already found within the application's safe domain (a third-party library). The Java solution is simple: during deserialization of external data, treat execute custom deserialization code as if it was foreign, and execute it within a foreign security context. It's best if this was done directly in the JDK code, and I assume a patch will adress this.