通常在java中解析XML时,可以通过使用
避免成为entity expansion attacks的受害者 dbf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
其中dbf是用于创建用于XML解析的DocumentBuilders的DocumentBuilderFactory。
但是,假设我正在使用JAXB解组某些XML,例如:像这样:
final JAXBContext context = JAXBContext.newInstance(MyClass.class);
final Unmarshaller unmarshaller = context.createUnmarshaller();
final MyClass result = (MyClass) unmarshaller.unmarshal(input);
如何配置JAXB以在基础XML解析器上使用FEATURE_SECURE_PROCESSING?
谷歌搜索答案会带来以下最佳结果: http://forums.java.net/node/699983
但是,我不想引入XMLStreamFactory等实现只是为了使实体扩展可配置。有没有办法只使用JAXB API来解决这个问题?
答案 0 :(得分:10)
Java SE 5将实体扩展数限制为64,000:
我希望所有JAXB实现都会保留此默认保护。但是,如果您想100%确定,您可以通过以下方式创建SAXSource并让JAXB解组:
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
SAXParser sp = spf.newSAXParser();
XMLReader xmlReader = sp.getXMLReader();
SAXSource saxSource = new SAXSource(xmlReader, inputSource);
有关详细信息,请参阅:
答案 1 :(得分:1)
我使用的代码与Blaise的答案非常相似,最近发现它有一个微妙的问题。我从SAXParser获得的XMLReader没有配置为理解命名空间,这意味着它没有正确处理可填充的元素,如
<myType>
<myIntegerElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</myType>
而不是JAXB将myIntegerElement解组为Java中的null
整数,而是解码为Integer.valueOf(0)
;我的代码的一个重要区别。解决方案是将解析器工厂设置为名称空间感知:
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
SAXParser sp = spf.newSAXParser();
// and so on
我发现这非常令人惊讶,因为如果我通过XMLReaderFactory.createXMLReader()
得到我的XMLReader,那么读者对可支持的元素没有问题,但它也不理解XMLConstants.FEATURE_SECURE_PROCESSING。
答案 2 :(得分:0)
嗯,首先xmlstreamfactory的东西是jdk的一部分,所以你不需要“引入它们”。第二,你总是可以自己(安全地)解析DOM,然后在DOM而不是原始流上执行JAXB。最后,您还可以创建自己的SAXParser(配置为安全处理),并将其传递给JAXB(Blaise提到,只是看到了)(jdk中的内置jaxb impl使用来自SAXParser的XMLReader作为内部解析器的InputStream)。
答案 3 :(得分:0)
javax.xml.parsers.SAXParserFactory
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
SAXParser sp = spf.newSAXParser();
XMLReader xmlReader = sp.getXMLReader();
SAXSource saxSource = new SAXSource(xmlReader, inputSource);