jaxb unmarshal abusable созданным xml при использовании синтаксического анализатора по умолчанию? - PullRequest
4 голосов
/ 28 октября 2009

Так что в моем текущем проекте я использую 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.

Я относительный новичок в этом, так что, возможно, я чего-то упускаю. Пожалуйста, дайте мне знать, если так!

1 Ответ

4 голосов
/ 29 октября 2009

Хорошо продуманный вопрос, он заслуживает ответа:)

Некоторые вещи на заметку:

  1. Время выполнения JAXB не зависит от схемы XML. Он использует синтаксический анализатор SAX для генерации потока событий SAX, который он использует для привязки к объектной модели. Эта объектная модель может быть написана от руки или может быть сгенерирована из схемы с использованием XJC, но привязка и среда выполнения очень отличаются друг от друга. Так что вы можете знать, что хороший ввод XML соответствует схеме во время выполнения, но JAXB - нет.
  2. Принудительная загрузка во время выполнения удаленной ссылки DTD не представляет собой дыру в безопасности. Если в конце есть реальный DTD, то в худшем случае он не будет проверен. Если это не настоящий DTD, он будет проигнорирован.
  3. DTD считается устаревшим, поэтому прямой поддержки его в API JAXB высокого уровня нет. Если вам нужен EntityResolver, вам нужно изучить API SAX, что вы уже сделали.
  4. Если ваша модель класса была сгенерирована из XML-схемы, то вам следует рассмотреть возможность проверки ее во время выполнения, используя SchemaFactory и Unmarshaller.setSchema(). Это даст команду Xerces проверять события SAX по схеме перед передачей в JAXB. Это не остановит выборку DTD, но добавляет уровень безопасности, который, как вы знаете, хорош для данных.
...