Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent XXE Attack with JAXB

Recently, we had a security audit on our code, and one of the problem is that our application is subject to the Xml eXternal Entity (XXE) attack.

Basically, the application is a calculator that receives inputs as XML, through a Web-Service.

Here is an example of such an XXE attack on our application:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">    <soapenv:Header/>    <soapenv:Body>       <foo:calculateStuff>          <!--Optional:-->          <xmlInput><![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE currency [      <!ENTITY include SYSTEM "file:///d:/" >]> <calcinput>...</calcinput> ]]></xmlInput>       </foo:calculateStuff>    </soapenv:Body> </soapenv:Envelope> 

As you can see, we can refer to an entity that points to an external file ("file:///d:/").

Regarding the XML input itself (the <calcinput>...</calcinput> part) is unmarshalled with JAXB (v2.1). The web-service part is based on jaxws-rt (2.1).

What do I need to do to secure my web-service?

like image 411
Romain Linsolas Avatar asked Oct 19 '12 15:10

Romain Linsolas


People also ask

Which can be used to prevent XXE?

The safest way to prevent XXE is always to disable DTDs (External Entities) completely. Depending on the parser, the method should be similar to the following: factory. setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

How do you mitigate XXE?

In most cases, XXE attacks can easily be prevented by disabling features making the XML processor weak and the application vulnerable. By analyzing the XML parsing library of the application, features that can be misused can be identified and disabled. DTD and XML external entity features must be disabled.

Is JAXB memory efficient?

Generally JAXB is quite efficient and you shouldn't care about memory issues unless your application handles XMLs of very large size.


1 Answers

JAXB

You can prevent the Xml eXternal Entity (XXE) attack by unmarshalling from an XMLStreamReader that has the IS_SUPPORTING_EXTERNAL_ENTITIES and/or XMLInputFactory.SUPPORT_DTD properties set to false.

JAX-WS

A JAX-WS implementation should take care of this for you. If it doesn't I would recommend opening a bug against the specific implmententation.


EXAMPLE

Demo

package xxe;  import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource;  public class Demo {      public static void main(String[] args) throws Exception {         JAXBContext jc = JAXBContext.newInstance(Customer.class);          XMLInputFactory xif = XMLInputFactory.newFactory();         xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);         xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);         XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/xxe/input.xml"));          Unmarshaller unmarshaller = jc.createUnmarshaller();         Customer customer = (Customer) unmarshaller.unmarshal(xsr);          Marshaller marshaller = jc.createMarshaller();         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);         marshaller.marshal(customer, System.out);     }  } 

input.xml

This XML document contains an entity that has been setup to get the listing of files I used to create this example.

<?xml version="1.0"?> <!DOCTYPE customer [ <!ENTITY name SYSTEM "/Users/bdoughan/Examples/src/xxe/"> ] > <customer>   <name>&name;</name> </customer> 

Customer

package xxe;  import javax.xml.bind.annotation.XmlRootElement;  @XmlRootElement public class Customer {      private String name;      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }  } 

Output - Default Configuration

By default the entity will be resolved.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <customer>     <name>Customer.java Demo.java input.xml </name> </customer> 

Output when XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES property is set to false

When this property is set the entity is not resolved.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <customer>     <name></name> </customer> 

Output when XMLInputFactory.SUPPORT_DTD property is set to false

When this property is set an exception is thrown trying to resolve the entity.

Exception in thread "main" javax.xml.bind.UnmarshalException  - with linked exception: [javax.xml.stream.XMLStreamException: ParseError at [row,col]:[8,15] Message: The entity "name" was referenced, but not declared.]     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:436)     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:372)     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:342)     at xxe.Demo.main(Demo.java:18) Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[8,15] Message: The entity "name" was referenced, but not declared.     at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:598)     at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:196)     at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:370)     ... 2 more 
like image 136
bdoughan Avatar answered Sep 28 '22 00:09

bdoughan