Is there a way to completely disable java deserialization?
Java deserialization as in java.io.ObjectInputStream potentially opens an application to security issues by deserializing so-called serialization gadgets.
I do not use java serialization intentionally, but it is hard to make sure no library that is trusted with some outside input will never perform deserialization. For this reason I would love some kind of kill switch to disable serialization completely.
This is different from caching issues - I want to make sure no object is ever deserialized in my application, including through libraries.
A simple way to prevent deserialization is to define an agressive deserialization filter (introduced in Java 9 via JEP 290).
For example with java -Djdk.serialFilter=maxbytes=0 MyApp, any deserialization attempt (byte stream size > 0 byte) will throw an java.io.InvalidClassException: filter status: REJECTED exception.
Or you could use maxrefs=0, or simply exclude all classes using a wildcard, i.e. java -Djdk.serialFilter=!* MyApp or java -Djdk.serialFilter='!*' MyApp on Unix where the "!" needs to be escaped.
You can use a Java agent to do that. Try this one. Also, a nice read is this blog post discussing more on the topic of disabling deserialization.
Related
I have noticed in my web based project, we are implementing Serialization in every DTO class and not using ObjectOutputStream/ObjectInputStream anywhere in project, while in every serialization tutorial they are using ObjectOutput/InputStream. Does serialization happen even without it? (i.e. stream conversion and sending it over network without using ObjectOutputStream/ObjectInputStream)?
Does serialization happen even without it? (i.e. stream conversion and sending it over network without using ObjectOutputStream/ObjectInputStream)?
First of all, Serialization doesn't necessarily have anything to do with a network (or a temp file as per your original question).
Secondly, Java Object Serialisation by definition involves java.io.Serializable and java.io.ObjectOutputStream.
Thirdly, there are other things beside your own code executing in any application. The JRE classes, for a start. It is open to any of those to use Serialization. For example, and please note that this is a list of examples, without the slightest pretension to being exhaustive:
RMI
Serialization of sessions by web containers
EJB, which is built on RMI
Object messages in JMS
...
We are migrating a system written in C to Java and must retain existing processes (no debate). We currently "embed" compile-time information into the C application using the C preprocessor, for example:
cc -o xxx.o -DCOMP_ARG='"compile time arg"' xxx.c
The xxx.c file can then use "COMP_ARG" and its value will be embedded in the code and we have little worry about it being changed inadvertently.
We realize Java likes to use properties files, however, our requirements are such that some information ** ** be embedded in the code, so properties files are not an option - these certain values cannot be specified at runtime. To illustrate the point, such data could be a date-stamp of when the file was compiled, but the exact data is irrelevant to the question.
We are looking for a way to specify at compile time various values that are available to the Java code. We are quite aware that Java does not have a pre-processor as does C, so the mechanism would be different.
Our current solution is using a code generation step (Maven), which does work, however, Eclipse is wreaking havoc trying to deal with the source files so that we had turn off "Build Automatically". We really want to find a more robust solution.
We appreciate any help, thanks.
The xxx.c file can then use "COMP_ARG" and its value will be embedded
in the code and we have little worry about it being changed
inadvertently.
...our requirements are such that some information be embedded in the
code....
We are looking for a way to specify at compile time various values
that are available to the Java code. We are quite aware that Java does
not have a pre-processor as does C, so the mechanism would be
different.
It seems that the best way to solve this problem would be to make use of annotations in your code.
In Java, annotations are a kind of interface declaration, but they do not enforce a behavioral contract with an implementing class. Rather, they are meant to define a contract with some external framework, preprocessor, or with the compiler itself. Annotations are used extensively in Java EE 5.0 (and later) to specify configuration and behavior to the framework within which the developer's code runs. Annotations are also used extensively by the JavaDoc documentation processor. Here, the annotations in the doc comments allow you to specify and format the information which you intend to appear in the documentation when the JavaDoc processor runs.
Annotations can be defined to be accessible at runtime. In such a case, the primary mechanism for accessing annotations is the Java Reflection facility. For example, annotations with a retention policy of RUNTIME and defined on a class, can be accessed through that class's corresponding Class object:
Class myCls = MyClass.class; // the "class literal" for MyClass
Annotation[] annotations = myCls.getDeclaredAnnotations();
Annotations can include arguments for parameters to allow for more flexibility in configuration. The use of annotations is most convenient when the code itself can be so annotated.
A quick tutorial on how annotations are defined and used in Java is available here: https://docs.oracle.com/javase/tutorial/java/annotations/
I'm going to post my own answer which seems to be "Can't be done" - what can't be done, apparently, is provide at compile time to Java, a set of parameters that gets passed to the program at execution time. The solution appears to be to continue with what I am doing which is to update a Java source file with the compile-time data and figure out how to coax Eclipse to stop over-writing the files.
Thanks to everyone who commented.
https://github.com/frohoff/ysoserial
Is a proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization. It also works with JMX.
Is there any way to make JMX secure?
I also read https://tersesystems.com/2015/11/08/closing-the-open-door-of-java-object-serialization/. I dont understand how to use NotSoSerial in my project.
You can run NotSoSerial by building the project from githhub, then taking the jar and running the JVM with the following arguments on the command line:
-javaagent:notsoserial.jar -Dnotsoserial.whitelist=empty.txt
as specified in https://github.com/kantega/notsoserial#whitelisting-mode
If you want to use JMX but don't want to use RMI (which uses Java Serialization) then look into jmxtrans or Jolokia and see how you can best lock the JSON messages being passed through there.
I want to provide communication between many JVM using protobuf. Those JVM are executing a component-based middleware, hence there are arbitrary objects that I cannot anticipate because they are written by third-party developers.
The problem is that I want to free components' developer of the burden of specifying the serialization mechanism. I think this decision has some advantages:
There are legacy components that were written without thinking in a specific serialization mechanism (in fact, they use built-in java serialization)
If the channel manages the encoding/decoding of messages then you can connect any pair of components
It is easier to write components.
However, the only way of doing automatic serialization is using java built-in serialization, but as we all know that's very slow. So, my question is: Can we create a mechanism to, given a Java Object, build a protobuf messsage with its content that we can send to another process??
I am aware that this is not the way you should use protobuf and I can see some problems. Let me first explain how I think we can achieve my goal.
If an object (O) of the class (C) has never been serialized go to to step 2; otherwise, we already have a message class to serialize this class and we can go to step 7.
Build a proto specification using reflection on class C as the built-in serialization does.
Generate message class using protoc
Build the generated class using the java compiler.
Generate class on the fly using ASM for bytecode manipulation. This class will transform O into a message we can send. It will also perform the opposite transformation.
Save in a cache all the classes generated for objects of class C
Use the class generated in 5 to create a message.
Send the message with whatever mechanism the channel supports (i.e. sockets, shared memory)
Note 1: You can see that we are doing this on one side of the communication channel, we need to do that on both sides. I think, it is possible to send the first message using built-in serialization (use the first object to build the protobuf message) and further objects with protobuf.
Note 2: Step 5 is not required, but it is useful to avoid reflection every time you send an object.
Note 3: Protobuf is not mandatory here. I am including it because maybe it offers some tool to deal with the problem I have.
I can see that there is a lot of work to do. I can also see that maybe it won't work in some corner cases. Thus, I am wondering if there is some library already built and capable of doing that?
I have a post-compilation step that manipulates the Java bytecode of generated classes. I'd like to make life as painless as possible for library consumers, so I'm looking at ways I can make this process automatic and (if possible) compiler agnostic.
The Annotation Processing API provides many of the desired features (automatic service discovery; supported by Eclipse). Unfortunately, this is aimed at code generators and doesn't support manipulation of existing artefacts:
The initial inputs to the tool are
considered to be created by the zeroth
round; therefore, attempting to create
a source or class file corresponding
to one of those inputs will result in
a FilerException.
The Decorator pattern recommended by the API is not an option.
I can see how to perform the step with a runtime agent/instrumentation, but this is a worse option than a manual build step as it would require anyone even peripherally touched by the API to configure their JVMs in a non-obvious manner.
Is there a way to plug into or wrap the compiler tool as invoked by javac? Has anyone successfully subverted the annotation processors to manipulate bytecode, no matter what the doc says?
The Groovy compiler is the only bytecode compiler which allows to hook into the compilation process (example: Generate bytecode to support the Singleton pattern)
The Annotation Processing API is not meant to change the code. As you have already found out, all you can do is install a classloader, examine the bytecode at runtime and manipulate it. It's braindead but it works. This follows the general "we're afraid that a developer could try something stupid" theme which you will find throughout Java. There is no way to extend javac. The relevant classes are either private, final or will change with the next version of Java.
Another option is to write annotated Java, for example you write a class "ExampleTpl.java". Then, you use a precompiler which expands the annotations in that file to get "Example.java". In the rest of the code, you use Example and ignore ExampleTpl.
For Eclipse, there is a bug report to automate this step. I'm not aware of any other work in this area.
It can be done.
Take a look at my blog post Roman Numerals, in our Java where an annotation processor is used to rewrite code. Limitation being that it works with Sun's javac only.