jaxb unmarshal abusable por xml diseñado cuando se utiliza el analizador sax por defecto?

StackOverflow https://stackoverflow.com/questions/1638528

  •  08-07-2019
  •  | 
  •  

Pregunta

Entonces, en mi proyecto actual, uso el JAXB RI con el analizador Java predeterminado del JRE de Sun (que creo que es Xerces) para desarmar XML arbitrario.

Primero uso XJC para compilar un XSD de la siguiente forma:

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema attributeFormDefault="unqualified" 
elementFormDefault="qualified" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xs:element name="foobar">
...
</xs:element> 
</xs:schema>

En el " buen caso " Todo funciona según lo diseñado. Es decir, si se me pasa XML que se ajusta a este esquema, JAXB lo descompone correctamente en un árbol de objetos.

El problema surge cuando me pasan XML con referencias externas de DTD, por ejemplo,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foobar SYSTEM "http://blahblahblah/foobar.dtd">
<foobar></foobar>

Al descomponer algo como esto, el analizador SAX intenta cargar la entidad remota (" http: // somehost / foobar .dtd ") a pesar de que este fragmento claramente no se ajusta al esquema que compilé anteriormente con XJC.

Para eludir este comportamiento, dado que sé que cualquier XML conforme (de acuerdo con el XSD que compilé) nunca requerirá la carga de una entidad remota, tengo que definir un EntityResolver personalizado que cortocircuite la carga de todos los remotos entidades. Entonces, en lugar de hacer algo como:

MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(myReader);

Me veo obligado a hacer esto:

XMLReader myXMLReader = mySAXParser.getXMLReader();
myXMLReader.setEntityResolver(myCustomEntityResolver);
SAXSource mySAXSource = new SAXSource(myXMLReader, new InputSource(myReader));
MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(mySAXSource);

Entonces mi última pregunta es:

Al desarticular con JAXB, ¿debería la carga de entidades remotas por el analizador SAX subyacente ser automáticamente en cortocircuito cuando el XML en cuestión puede reconocerse como no válido sin la carga de esas entidades remotas?

Además, ¿no parece esto un problema de seguridad? Dado que JAX-WS se basa en JAXB bajo el capó, parece que podría pasar XML especialmente diseñado a cualquier servicio web basado en JAX-WS y hacer que el host WS cargue cualquier URL arbitraria.

Soy un novato relativo a esto, así que probablemente hay algo que me falta. ¡Avísame si es así!

¿Fue útil?

Solución

Una pregunta bien elaborada, merece una respuesta :)

Algunas cosas a tener en cuenta:

  1. El tiempo de ejecución JAXB no depende del esquema XML. Utiliza un analizador SAX para generar una secuencia de eventos SAX que utiliza para unirse al modelo de objetos. Este modelo de objetos puede escribirse a mano o puede generarse a partir de un esquema utilizando XJC, pero el enlace y el tiempo de ejecución son muy distintos entre sí. Entonces usted puede saber que una buena entrada XML se ajusta al esquema en tiempo de ejecución, pero JAXB no lo hace.
  2. Forzar el tiempo de ejecución para cargar una referencia DTD remota no constituye un agujero de seguridad. Si hay una DTD real al final, el peor de los casos es que no se validará. Si no es una DTD real, se ignorará.
  3. DTD se considera obsoleto, por lo que no hay soporte directo para ello en la API JAXB de alto nivel. Si necesita un EntityResolver , debe profundizar en la API SAX, que ya ha hecho.
  4. Si su modelo de clase se generó a partir de un Esquema XML, entonces debería considerar validarlo en tiempo de ejecución, usando SchemaFactory y Unmarshaller.setSchema () . Esto le indicará a Xerces que valide los eventos SAX contra el esquema antes de pasarlos a JAXB. Esto no detendrá la obtención de la DTD, pero agrega una capa de seguridad que usted sabe que los datos son buenos.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top