java - vulnerabilidad - Prevenir el ataque XXE con JAXB
xxe vulnerabilidad (1)
JAXB
Puede evitar el ataque de Xml eXternal Entity (XXE) desmarcando de un XMLStreamReader
que tiene las IS_SUPPORTING_EXTERNAL_ENTITIES
y / o XMLInputFactory.SUPPORT_DTD
establecidas en false
.
JAX-WS
Una implementación JAX-WS debería encargarse de esto por usted. Si no lo hace, recomendaría abrir un error contra la implmententación específica.
EJEMPLO
Manifestación
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
Este documento XML contiene una entidad que se ha configurado para obtener la lista de archivos que utilicé para crear este ejemplo.
<?xml version="1.0"?>
<!DOCTYPE customer
[
<!ENTITY name SYSTEM "/Users/bdoughan/Examples/src/xxe/">
]
>
<customer>
<name>&name;</name>
</customer>
Cliente
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;
}
}
Salida - Configuración predeterminada
Por defecto, la entidad se resolverá.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<name>Customer.java
Demo.java
input.xml
</name>
</customer>
Salida cuando la propiedad XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES
se configura como false
Cuando se establece esta propiedad, la entidad no se resuelve.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<name></name>
</customer>
Salida cuando la propiedad XMLInputFactory.SUPPORT_DTD
está configurada como false
Cuando se establece esta propiedad, se lanza una excepción tratando de resolver la entidad.
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
Recientemente, tuvimos una auditoría de seguridad en nuestro código, y uno de los problemas es que nuestra aplicación está sujeta al ataque Xml EXternal Entity (XXE).
Básicamente, la aplicación es una calculadora que recibe entradas como XML a través de un servicio web.
Aquí hay un ejemplo de dicho ataque XXE en nuestra aplicación:
<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>
Como puede ver, podemos hacer referencia a una entidad que apunta a un archivo externo ( "file:///d:/"
).
Con respecto a la entrada XML en sí misma (la parte <calcinput>...</calcinput>
) no está coordinada con JAXB (v2.1). La parte del servicio web se basa en jaxws-rt (2.1).
¿Qué debo hacer para proteger mi servicio web?
Gracias.