jaxb unmarshal peut-il être utilisé abusivement par un fichier xml construit lors de l’utilisation de l’analyseur sax par défaut?

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

  •  08-07-2019
  •  | 
  •  

Question

Donc, dans mon projet actuel, j'utilise le RI JAXB avec l'analyseur Java par défaut du JRE de Sun (ce qui, à mon avis, est Xerces) pour annuler la gestion du code XML arbitraire.

J'utilise d'abord XJC pour compiler un fichier XSD de la forme suivante:

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

Dans le "bon cas" tout fonctionne comme prévu. C’est-à-dire que si je reçois du code XML conforme à ce schéma, JAXB le décompose correctement dans une arborescence d’objets.

Le problème survient lorsque je suis passé au format XML avec une référence DTD externe, par exemple

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

Une fois que cela a été fait, l’analyseur SAX tente de charger l’entité distante (" http: // somehost / foobar .dtd ") bien que ce fragment de code ne soit clairement pas conforme au schéma que j'avais précédemment compilé avec XJC.

Afin de contourner ce problème, étant donné que je sais que tout XML conforme (conformément au XSD que j'ai compilé) ne nécessitera jamais le chargement d'une entité distante, je dois définir un EntityResolver personnalisé qui court-circuite le chargement de tous les périphériques distants. entités. Donc, au lieu de faire quelque chose comme:

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

Je suis obligé de faire ceci:

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

Ma dernière question est donc la suivante:

Lors de la suppression du langage JAXB, le chargement d'entités distantes par l'analyseur SAX sous-jacent doit-il être automatiquement court-circuité lorsque le code XML en question peut être reconnu comme non valide sans le chargement de ces entités distantes?

De plus, cela ne semble-t-il pas être un problème de sécurité? Étant donné que JAX-WS s'appuie sur JAXB sous le capot, il semble que je puisse transmettre du code XML spécialement conçu à tout service Web basé sur JAX-WS, ce qui permet à l'hôte WS de charger toute URL arbitraire.

Je suis un débutant dans ce domaine, donc il manque probablement quelque chose. S'il vous plaît laissez-moi savoir si oui!

Était-ce utile?

La solution

Une question bien conçue qui mérite une réponse:)

Quelques points à noter:

  1. Le moteur d’exécution JAXB ne dépend pas du schéma XML. Il utilise un analyseur SAX pour générer un flux d'événements SAX qu'il utilise pour se lier au modèle d'objet. Ce modèle d'objet peut être écrit à la main ou peut être généré à partir d'un schéma utilisant XJC, mais la liaison et l'exécution sont très distinctes l'une de l'autre. Ainsi, vous savez peut-être qu'une bonne entrée XML est conforme au schéma à l'exécution, contrairement à JAXB.
  2. Forcer le runtime à charger une référence DTD distante ne constitue pas une faille de sécurité. S'il y a une vraie DTD à la fin, le pire des cas est qu'elle ne sera pas validée. Si ce n'est pas une vraie DTD, elle sera ignorée.
  3. La DTD étant considérée comme obsolète, elle n’est pas directement prise en charge dans l’API JAXB de haut niveau. Si vous avez besoin d’un EntityResolver , vous devez creuser dans l’API SAX, ce que vous avez déjà fait.
  4. Si votre modèle de classe a été généré à partir d'un schéma XML, vous devez envisager de le valider au moment de l'exécution, en utilisant SchemaFactory et Unmarshaller.setSchema () . Cela indiquera à Xerces de valider les événements SAX par rapport au schéma avant d'être transmis à JAXB. Cela n'arrêtera pas l'extraction de la DTD, mais cela ajoutera une couche de sécurité indiquant que les données sont bonnes.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top