Known vulnerabilities associated with JAXB unmarshalling are:
- XXE
- billion laughs
- RCE
which are due to deserialization of untrusted data and the resolution of external references. I'm aware of the following settings to be recommended for JAXB in order to protect from (1) and (2):
val factory = XMLInputFactory.newInstance factory.setProperty(XMLConstants.FEATURE_SECURE_PROCESSING, true); factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); val xmlReader = factory.createXMLStreamReader(new StringReader(xml))
In order to prevent (3), i.e., in order to prevent unmarshalling unexpected objects, I know the best way is to whitelist the classes that can be instantiated over XML by customising the JAXB mapping method.
However, I could not find a single example of this anywhere at all.
(I do not suppose "unmarshalling by declared type" is going to help, given the method description - quoting:
The unmarshal methods with a declaredType parameter enable an application to deserialize a root element of XML data, even when there is no mapping in JAXBContext of the root element's XML name
which means that the following:
val elem: JAXBElement[MyClassType] = unmarshaller.unmarshal(xmlReader, classOf[MyClassType])
has nothing to do with restricting the unmarshalling only to the specified class.)
I would be very grateful if someone could provide a concrete sample code showing how to protect against (3) when using JAXB (I know that for other java deserialisations one should use the "Lookahead ObjectInputStream" but for JAXB that solution doesn't apply) - thanks a million!