问题描述
我对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);
}
}
基于答案,而不是使用ByteArrayInputStream
,我应该使用具有某些属性false
的XMLStreamReader
.
在建议的答案中,它表示:
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/xxe/input.xml"));
我不知道什么是"src/xxe/input.xml",它对于我的解决方案来说是必需的.谁能解释一下?
另一个问题的答案中的src/xxe/input.xml
是该问题正在处理的XML的源位置-即作为URL资源访问的文件名. /p>
在您的情况下,您的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);
I am very new to JAXB and in our code audit, there was suggestion on preventing XXE attack with JAXB. I found related answer: Prevent XXE Attack with JAXB
My existing code looks like this:
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);
}
}
Based on the answer, instead of using ByteArrayInputStream
, I am supposed to use XMLStreamReader
with some properties false
.
In suggested answer, it says:
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/xxe/input.xml"));
I don't understand what 'src/xxe/input.xml' is and what it needs to be for my solution. Can anyone please explain?
The src/xxe/input.xml
from the answer in the other question is that question's source location for the XML being processed - namely a filename, accessed as a URL resource.
In your case, your XML is provided in String manifestString
- therefore your StreamSource
needs to be given this string as its source, not a file location.
This can be done using a StringReader
:
import java.io.StringReader
...
StringReader manifestReader = new StringReader(manifestString);
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(manifestReader));
I split the code into 2 lines to make it clearer - but you can collapse them back to one line if you prefer:
XMLStreamReader xsr = xif.createXMLStreamReader(
new StreamSource(new StringReader(manifestString)));
The above code assumes you have already created your context and the xif
input factory:
JAXBContext jc = JAXBContext.newInstance(Manifest.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
Then you can unmarshal in the usual way:
Unmarshaller unmarshaller = jc.createUnmarshaller();
Manifest manifest = (Manifest) unmarshaller.unmarshal(xsr);
这篇关于使用JAXB XMLStreamReader防止XXE攻击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!