How to disable DTD fetching using JAXB2.0

22,375

Solution 1

Below is sample code that demonstrates how to get a JAXB (JSR-222) implementation to use your SAX parser:

import java.io.FileReader;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        XMLReader xmlReader = spf.newSAXParser().getXMLReader();
        InputSource inputSource = new InputSource(new FileReader("input.xml"));
        SAXSource source = new SAXSource(xmlReader, inputSource);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Foo foo = (Foo) unmarshaller.unmarshal(source);
        System.out.println(foo.getValue());
    }

}

Solution 2

Building on the answers from @blaise-doughan and @aerobiotic, here is a solution that worked for me:

import java.io.FileReader;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXSource;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

public class Demo2 {

    public static void main(String[] args) throws Exception {

        JAXBContext jc = JAXBContext.newInstance(MyBean.class);

        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        spf.setFeature("http://xml.org/sax/features/validation", false);

        XMLReader xmlReader = spf.newSAXParser().getXMLReader();
        InputSource inputSource = new InputSource(
                new FileReader("myfile.xml"));
        SAXSource source = new SAXSource(xmlReader, inputSource);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        MyBean foo = (MyBean) unmarshaller.unmarshal(source);
    }
}

Solution 3

In answer to the question "How to disable DTD fetching using JAXB2.0".

@sameer-puri links to https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#SAXTransformerFactory which answers the question as follows:

JAXB Unmarshaller

Since a javax.xml.bind.Unmarshaller parses XML and does not support any flags for disabling XXE, it's imperative to parse the untrusted XML through a configurable secure parser first, generate a source object as a result, and pass the source object to the Unmarshaller. For example:

//Disable XXE
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

//Do unmarshall operation
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(),
                                new InputSource(new StringReader(xml)));
JAXBContext jc = JAXBContext.newInstance(Object.class);
Unmarshaller um = jc.createUnmarshaller();
um.unmarshal(xmlSource);
Share:
22,375

Related videos on Youtube

Nick
Author by

Nick

Updated on July 29, 2021

Comments

  • Nick
    Nick over 2 years

    I'm trying to use JAXB to unmashall some XML which I used xjc to create in the first place. I don't want to do any validation on the unmarshalling, but even though I have disabled the validation according to the JAXB documentation with u.setSchema(null);, but this hasn't prevented a FileNotFoundException being thrown when it tries to run and can't find the schema.

    JAXBContext jc = JAXBContext.newInstance("blast");
    Unmarshaller u = jc.createUnmarshaller();
    u.setSchema(null);
    return u.unmarshal(blast)
    

    I've seen similar questions for disabling SAX parsing from validation by setting the apache property http://apache.org/xml/features/validation/schema to false, but I can't get the Unmarshaller to use my own sax parser.

  • aerobiotic
    aerobiotic almost 12 years
    That didn't work for me but these did: parser.setFeature("apache.org/xml/features/nonvalidating/loa‌​d-external-dtd", false); parser.setFeature("xml.org/sax/features/validation", false);
  • Sameer Puri
    Sameer Puri over 7 years
    This website explains how it can be blocked on any of the major Java frameworks.
  • gihan-maduranga
    gihan-maduranga over 7 years
    This worked for me.Also additionally added spf.setValidating(false); Thanks
  • ahmettolga
    ahmettolga over 4 years
    Seems that FEATURE_SECURE_PROCESSING is about entityExpansionLimit. Check the last part of the documentation docs.oracle.com/javase/1.5.0/docs/guide/xml/jaxp/…
  • Graham Leggett
    Graham Leggett over 3 years
    This answers the question "how do I get the Unmarshaller to use my own sax parser", but does not answer the question "How to disable DTD fetching using JAXB2.0".