How to validate an object before deserializing
In case anyone visits this old post, I got around this issue by switching from ObjectMessage to TextMessage and just sending JSON instead of serialized objects.
This post was very informative
//Sender
ObjectMapper mapper = new ObjectMapper();
TextMessage message = session.createTextMessage(mapper.writeValueAsString(foo));
messageBus.send(message);
//Receiver
ObjectMapper mapper = new ObjectMapper();
try {
Foobar foo= mapper.readValue(textMessage.getText(), new TypeReference<Foobar>(){});
dataHandlerProcess(foo);
} catch (IOException e) {
logger.error("Could not parse Foobar JSON ",e );
return;
}
If you look at the tips portion from the recommendations it states that the issue will be reported even if a look-ahead ObjectInputStream is implemented. Therefore even if you were able to fix the issue, you will not get rid of the finding.
However, it looks like your code is using JMS and with JMS, you do not control the deserialization. This is recognized by the recommendations you copied and pasted:
When deserialization takes place in library, or framework (e.g. when using JMX, RMI, JMS, HTTP Invokers) the above recommendation is not useful since it is beyond the developer's control. In those cases, you may want to make sure that these protocols meet the following requirements:
- Not exposed publicly.
- Use authentication.
- Use integrity checks.
- Use encryption.
Therefore, your true fix is to ensure those four bullet points are followed. You will have to do research into your connection and, depending on your requirements and limitations, that may not be possible.
Take a look at the ValidatingObjectInputStream. Basically you whitelist the classes that you will allow to be deserialized (you should know these based on the info you are pulling in). The validator will then check the metadata to the serialized data and reject any classes that are not within the whitelist.