jaxb unmarshal abusable созданным xml при использовании синтаксического анализатора по умолчанию?
Вопрос
Так что в моем текущем проекте я использую RI JAXB с Java-анализатором по умолчанию из JRE Sun (который я считаю Xerces), чтобы демаршировать произвольный XML.
Сначала я использую XJC для компиляции XSD следующей формы:
<?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>
В "хорошем случае" все работает как задумано. То есть, если я передал XML, соответствующий этой схеме, JAXB правильно демарширует его в дерево объектов.
Проблема возникает, когда мне передают XML с внешними ссылками DTD, например.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foobar SYSTEM "http://blahblahblah/foobar.dtd">
<foobar></foobar>
После удаления чего-либо подобного парсер SAX пытается загрузить удаленный объект (" http: // somehost / foobar .dtd ") несмотря на то, что этот фрагмент явно не соответствует схеме, скомпилированной ранее с XJC.
Чтобы обойти это поведение, поскольку я знаю, что любой совместимый XML (в соответствии с скомпилированным XSD) никогда не потребует загрузки удаленной сущности, я должен определить пользовательский EntityResolver, который закорачивает загрузку всех удаленных юридические лица. Поэтому вместо того, чтобы делать что-то вроде:
MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(myReader);
Я вынужден сделать это:
XMLReader myXMLReader = mySAXParser.getXMLReader();
myXMLReader.setEntityResolver(myCustomEntityResolver);
SAXSource mySAXSource = new SAXSource(myXMLReader, new InputSource(myReader));
MyClass foo = (MyClass) myJAXBContext.createUnmarshaller().unmarshal(mySAXSource);
Итак, мой последний вопрос:
При демаршалинге с JAXB, должна ли загрузка автоматически загружаться удаленными сущностями базовым синтаксическим анализатором SAX, когда рассматриваемый XML может быть признан недействительным без загрузки этих удаленных сущностей? р>
Кроме того, это не похоже на проблему безопасности? Учитывая, что JAX-WS опирается на JAXB изнутри, кажется, что я мог бы передать специально созданный XML-файл любому веб-сервису на основе JAX-WS и заставить хост WS загружать любой произвольный URL.
Я относительный новичок в этом, так что, возможно, мне чего-то не хватает. Пожалуйста, дайте мне знать, если так!
Решение
Хорошо продуманный вопрос, он заслуживает ответа:)
Некоторые вещи, на которые стоит обратить внимание:
<Ол> EntityResolver
, вам нужно изучить API SAX, что вы уже сделали. SchemaFactory
и Unmarshaller.setSchema ()
. Это даст команду Xerces проверять события SAX по схеме перед передачей в JAXB. Это не остановит выборку DTD, но добавляет уровень безопасности, который, как вы знаете, хорош для данных.