Domanda

Quindi nel mio attuale progetto uso JAXB RI con il parser Java predefinito da Sun's JRE (che credo sia Xerces) a XML arbitrario non comune.

Per prima cosa uso XJC per compilare un XSD nel seguente formato:

<?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>

Nel "buon caso" tutto funziona come previsto. Ciò significa che se mi viene passato un XML conforme a questo schema, JAXB lo rimuove correttamente in un albero degli oggetti.

Il problema si presenta quando ho passato XML con riferimenti DTD esterni, ad esempio

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

Dopo aver smascherato qualcosa del genere, il parser SAX tenta di caricare l'entità remota (" http: // somehost / foobar .dtd ") nonostante il fatto che questo frammento chiaramente non sia conforme allo schema che ho compilato in precedenza con XJC.

Al fine di aggirare questo comportamento, poiché so che qualsiasi XML conforme (secondo l'XSD che ho compilato) non richiederà mai il caricamento di un'entità remota, devo definire un EntityResolver personalizzato che cortocircuita il caricamento di tutti i remoti entità. Quindi invece di fare qualcosa del genere:

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

Sono costretto a farlo:

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

Quindi la mia ultima domanda è:

Durante l'annullamento del marshalling con JAXB, il caricamento di entità remote da parte del parser SAX sottostante deve essere automaticamente in corto circuito quando l'XML in questione può essere riconosciuto come non valido senza il caricamento di tali entità remote?

Inoltre, questo non sembra un problema di sicurezza? Dato che JAX-WS si basa su JAXB sotto il cofano, sembra che potrei passare XML appositamente predisposto a qualsiasi servizio Web basato su JAX-WS e fare in modo che l'host WS carichi qualsiasi URL arbitrario.

Sono un principiante relativamente a questo, quindi probabilmente c'è qualcosa che mi manca. Per favore fatemi sapere se è così!

È stato utile?

Soluzione

Una domanda ben fatta, merita una risposta :)

Alcune cose da notare:

  1. Il runtime JAXB non dipende dallo schema XML. Utilizza un parser SAX per generare un flusso di eventi SAX che utilizza per associarsi al modello a oggetti. Questo modello a oggetti può essere scritto a mano o può essere generato da uno schema usando XJC, ma l'associazione e il runtime sono molto distinti tra loro. Quindi tu potresti sapere che un buon input XML è conforme allo schema in fase di runtime, ma JAXB no.
  2. Forzare il runtime per caricare un riferimento DTD remoto non costituisce un buco di sicurezza. Se alla fine c'è un vero DTD, il caso peggiore è che non verrà convalidato. Se non è un vero DTD, verrà ignorato.
  3. La DTD è considerata obsoleta e quindi non è supportato direttamente nell'API JAXB di alto livello. Se hai bisogno di un EntityResolver , devi scavare nell'API SAX, cosa che hai già fatto.
  4. Se il tuo modello di classe è stato generato da uno schema XML, allora dovresti prendere in considerazione la convalida contro di esso in fase di esecuzione, usando SchemaFactory e Unmarshaller.setSchema () . Questo istruirà Xerces a convalidare gli eventi SAX sullo schema prima di essere passato a JAXB. Questo non impedirà il recupero del DTD, ma aggiunge un livello di sicurezza che sai che i dati sono buoni.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top