如何使用修复XXE漏洞产生的JAXB修复此Unmarshal异常?

时间:2018-08-27 14:44:03

标签: java xml jaxb xxe

我们应该处理的XML消息的格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:MessageType xmlns:ns0="http://www.path.to/some/schema.xsd">
    <ns0:NonRelevantBody>
        ....
    </ns0:NonRelevantBody>
</ns0:MessageType>

收到异常:

  

javax.xml.bind.UnmarshalException:意外元素(uri:“”,本地:“ ns0:MessageType”)。预期的元素是<{http://www.path.to/some/schema.xsd} MessageType>

上述异常发生在 com.xmlprocessor.MessageParser 类中。 所述类中的代码曾经是这样(并且已经使用了很长时间):

StringReader stringReader = new StringReader(xmlMessageAsString);

JAXBContext context = new JAXBContext.newInstance(MessageObjectFactory.class);
Unmarshaller unmarshalr = context.createUnmarshaller();
this.messageTypeContent = (MessageTypeContent) unmarshalr.unmarshal(stringReader);

结果证明这可能会给您XXE带来麻烦。因此,我们尝试了许多非常类似的工具DocumentBuilder,SAXParser等来禁用外部实体,文档类型声明等。所有人都给了我们与上述完全相同的例外。无论如何,这是SAXParser的更改:

StringReader stringReader = new StringReader(xmlMessageAsString);

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);

Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(stringReader));

JAXBContext context = new JAXBContext.newInstance(MessageObjectFactory.class);
Unmarshaller unmarshalr = context.createUnmarshaller();
this.messageTypeContent = (MessageTypeContent) unmarshalr.unmarshal(xmlSource);

com.xmlprocessor.MessageTypeContent 类的代码保持不变:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "messageType",
    "messageApprovalType"
})
@XmlRootElement(name = "MessageType")
public class MessageTypeContent {
    // Likely irrelevant unless you say so.
}

我尝试了很多方法,包括添加 namespace =“ ns0” namespace =“ http://www.path.to/some/schema.xsd” @XmlRootElement 注释,它会在运行时导致相同异常的相似版本。

请注意,代码中没有语法错误。我遇到的任何事情都在将其变成一个问题的过程中。我完全有可能错过一些极端的东西。如果您能指出这一点,我将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

让sax解析器名称空间知道可解决此问题:

spf.setNamespaceAware(true);

最后,废话少说。