Frage

So in meinem aktuellen Projekt verwende ich die JAXB RI mit dem Standard-Java-Parser von Sun JRE (was ich glaube, ist Xerces) beliebige XML zu entpacken.

Zuerst verwende ich XJC eine XSD der folgenden Form zu kompilieren:

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

In dem „guten Fall“ alles wie erwartet funktioniert. Das heißt, wenn ich XML übergeben würde, die zu diesem Schema entspricht dann JAXB richtig entpackt es in einen Objektbaum.

Das Problem kommt, wenn ich XML mit einer externen DTD Referenzen übergeben bin, z.

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

Auf so etwas wie dieses unmarshalling, der SAX-Parser versucht, die Remote-Einheit zu laden ( " http: // some / foobar. dtd ") trotz der Tatsache, dass diese Schnipsel eindeutig nicht das Schema I nicht entsprechen kompilierte früher mit XJC.

Um dieses Verhalten zu umgehen, da ich weiß, dass jede konformes XML (entsprechend der XSD ich kompiliert) erfordert nie das Laden einer entfernten Einheit, ich habe eine benutzerdefinierte EntityResolver zu definieren, dass Kurzschlüsse die Belastung aller Fern Einheiten. Anstatt also tun so etwas wie:

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

Ich bin gezwungen, dies zu tun:

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

So ist meine letzte Frage lautet:

Wenn Sie mit JAXB unmarshalling sollte das Laden von Remote-Einheiten von dem zugrunde liegenden SAX-Parser sein automatisch kurzgeschlossen, wenn die XML in Frage ohne die Belastung dieser entfernt gelegenen Einheiten als ungültig erkannt werden?

Auch dann, wenn dies nicht wie ein Sicherheitsproblem scheinen? Da die JAX-WS setzt auf JAXB unter der Haube, so scheint es, wie ich speziell gestaltetes XML einen JAX-WS-basierten Web-Service passieren könnte und den WS-Host verursache jede beliebige URL zu laden.

Ich bin ein relativ Neuling auf diesem, so gibt es wahrscheinlich etwas, was ich bin fehlt. Bitte lassen Sie mich wissen, ob so!

War es hilfreich?

Lösung

Eine gut gemachte Frage, die es verdient eine Antwort:)

Einige Dinge zu beachten:

  1. Die JAXB Laufzeit ist nicht abhängig von XML-Schema. Es verwendet einen SAX-Parser einen Strom von SAX Ereignissen zu erzeugen, die es auf das Objektmodell zu binden on verwendet. Dieses Objektmodell kann von Hand geschrieben sein, oder kann aus einem Schema erzeugt werden XJC verwenden, aber die Bindung und die Laufzeit ist sehr verschieden voneinander. So Sie können wissen, dass gute XML-Eingabe in das Schema zur Laufzeit entspricht, aber JAXB nicht.
  2. Erzwingen der Laufzeit eine Remote-DTD-Referenz laden stellt keine Sicherheitslücke. Wenn es am Ende der es sich um eine echte DTD ist, ist der schlimmste Fall, dass es nicht validiert werden. Wenn es nicht eine echte DTD ist, dann wird es ignoriert.
  3. DTD gilt als veraltet, und so gibt es keine direkte Unterstützung für sie in der hohen JAXB API. Wenn Sie ein EntityResolver benötigen, müssen Sie in den SAX-API graben, die Sie bereits getan haben.
  4. Wenn Ihr Klassenmodell aus einem XML-Schema erzeugt wurde, dann sollten Sie dagegen zur Laufzeit validiert, mit SchemaFactory und Unmarshaller.setSchema(). Dies wird anweisen Xerces die SAX Ereignisse gegen das Schema zu validieren, bevor zu JAXB weitergegeben werden. Dies wird nicht aufhören, die DTD geholt wird, aber es fügt eine Schicht von Sicherheit, die Sie wissen, dass die Daten gut ist.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top