使用JAXB XMLStreamReader防止XXE攻击



我是JAXB的新手,在我们的代码审计中,有人建议用JAXB防止XXE攻击。我找到了相关的答案:用JAXB 防止XXE攻击

我现有的代码如下:

if (properties.getProperty(MANIFEST) != null && !properties.getProperty(MANIFEST).isEmpty()) {
String manifestString =  properties.getProperty(MANIFEST);
ByteArrayInputStream is = new ByteArrayInputStream(manifestString.getBytes());
try {
this.manifest = (Manifest) getJaxbContext().createUnmarshaller().unmarshal(is);
}
catch (JAXBException e) {
LOG.warn("There was an error trying to convert xml String to Manifest - {}", e.getMessage(), e);
}

}

根据答案,我应该使用具有某些属性falseXMLStreamReader,而不是使用ByteArrayInputStream

在建议的答案中,它说:

XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/xxe/input.xml"));

我不明白"src/xxe/input.xml"是什么,以及我的解决方案需要什么。谁能解释一下吗?

另一个问题的答案中的src/xxe/input.xml是该问题中正在处理的XML的源位置,即作为URL资源访问的文件名。

在您的情况下,XML是在String manifestString中提供的,因此您的StreamSource需要将此字符串作为其源,而不是文件位置。

这可以使用StringReader:来完成

import java.io.StringReader
...
StringReader manifestReader = new StringReader(manifestString); 
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(manifestReader));

我把代码分成两行以使其更清晰,但如果你喜欢,你可以把它们折叠回一行:

XMLStreamReader xsr = xif.createXMLStreamReader(
new StreamSource(new StringReader(manifestString)));

上面的代码假设您已经创建了上下文和xif输入工厂:

JAXBContext jc = JAXBContext.newInstance(Manifest.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);

然后你可以用通常的方式进行解组:

Unmarshaller unmarshaller = jc.createUnmarshaller();
Manifest manifest = (Manifest) unmarshaller.unmarshal(xsr);

最新更新