== How to fix it in Java SE

=== Code examples

include::../../common/fix/code-rationale.adoc[]

==== Noncompliant code example

[source,java]
----
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // Noncompliant
----

==== Compliant solution

Protection from XXE can be done in several different ways. Choose one depending
on how the affected parser object is used in your code.

**1.** The first way is to completely disable `DOCTYPE` declarations:

[source, java]
----
// Applicable to:
// - DocumentBuilderFactory 
// - SAXParserFactory 
// - SchemaFactory
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

// For XMLInputFactory:
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
----

**2.** Disable external entity declarations completely:

[source, java]
----
// Applicable to:
// - DocumentBuilderFactory 
// - SAXParserFactory 
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

// For XMLInputFactory:
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
----

**3.** Prohibit the use of all protocols by external entities:

[source, java]
----
// `setAttribute` variant, applicable to:
// - DocumentBuilderFactory 
// - TransformerFactory 
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

// `setProperty` variant, applicable to:
// - XMLInputFactory 
// - SchemaFactory 
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

// For SAXParserFactory, the prohibition is done on child objects:
SAXParser parser = factory.newSAXParser();
parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
----

=== How does this work?

include::../../common/fix/xxe.adoc[]

=== Going the extra mile

==== Disable entity expansion
Specifically for `DocumentBuilderFactory`, it is possible to disable the entity
expansion. Note, however, that this does not prevent the retrieval of external
entities.

[source, java]
----
factory.setExpandEntityReferences(false);
----

