使用 JAXB XMLStreamReader 防止 XXE 攻击
Prevent XXE Attack with JAXB XMLStreamReader
我是 JAXB 的新手,在我们的代码审核中,有人建议使用 JAXB 防止 XXE 攻击。我找到了相关答案:Prevent XXE Attack with JAXB
我现有的代码如下所示:
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);
}
}
根据答案,我应该使用具有某些属性 false
.
的 XMLStreamReader
,而不是使用 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);
我是 JAXB 的新手,在我们的代码审核中,有人建议使用 JAXB 防止 XXE 攻击。我找到了相关答案:Prevent XXE Attack with JAXB
我现有的代码如下所示:
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);
}
}
根据答案,我应该使用具有某些属性 false
.
XMLStreamReader
,而不是使用 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);