Фон :
Я использую JAXB для демонтажа XML в объекты Java.Первоначально я использовал JAXB для выполнения демаршала.Затем был выполнен статический анализ кода, и была поднята проблема высокой критичности для инъекции внешнего объекта XML.После небольшого исследования я нашел предложение (https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_Unmarshaller) использовать синтаксический анализатор, настроенный для предотвращения синтаксического анализа внешних объектов. Был приведен пример того, что нужно сделать:
//Disable XXE
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
//Do unmarshall operation
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(new StringReader(xml)));
JAXBContext jc = JAXBContext.newInstance(Object.class);
Unmarshaller um = jc.createUnmarshaller();
um.unmarshal(xmlSource);
У меня нетсделал это точно так, как показано, но я думаю, что я сделал то же самое в действительности:
XMLReader reader = getXMLReader();
if (reader == null) {
logger.warn("Unable to create XML reader");
return;
}
JAXBContext context = JAXBContext.newInstance(messageClass);
Unmarshaller unmarshaller = context.createUnmarshaller();
for (File file : files) {
try {
InputSource source = new InputSource(new FileReader(file));
Source xmlSource = new SAXSource(reader, source);
JAXBElement<? extends BaseType> object =
(JAXBElement<? extends BaseType>) unmarshaller.unmarshal(xmlSource);
messages.add(object.getValue());
} catch (FileNotFoundException e) {
logger.error("Exception", e);
}
}
...
private XMLReader getXMLReader() {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (SAXNotRecognizedException | SAXNotSupportedException
| ParserConfigurationException e) {
logger.error("Exception", e);
}
XMLReader reader = null;
try {
reader = factory.newSAXParser().getXMLReader();
} catch (SAXException | ParserConfigurationException e) {
logger.error("Exception", e);
}
return reader;
}
Задача :
После внесения исправления, я теперь получаюисключение unmarshal, когда программа пытается прочитать в XML:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"ns1:TypeXYZ"). Expected elements are <{protected namespace URI}TypeABC>,...<{protected namespace URI}TypeXYZ>,...
До исправления, описанного выше, где я только что использовал JAXB для отмены маршалинга, она могла правильно проанализировать предоставленный XML без проблем.
Я предполагаю, что синтаксический анализатор SAX ожидает, что XML предоставит дополнительную информацию, которая отсутствует, или что он должен быть сконфигурирован так, чтобы игнорировать все, на что он жалуется. Я попробовал несколько других «функций» (http://xml.org/sax/features/namespace-prefixes=true и http://xml.org/sax/features/validation=false),, но это не решило проблему.
У меня нет контроля над схемой XML, которая определяет типы XML, и при этом я не имею контроля над тем, как соответствующий Java классы создаются.
Любая информация, которая поможет мне понять, что происходит, и которая помогает мне решить эту проблему, будет очень цениться.