【问题标题】:Document to String using DocumentBuilderFactory?使用 DocumentBuilderFactory 将文档转换为字符串?
【发布时间】:2015-05-01 18:08:48
【问题描述】:

我正在尝试找到将Document 转换为String 的方法,并在此处找到此XML Document to String? 帖子。但是,我想进行转换without using TransformerFactory because of XXE Vulnerabilities 并仅使用DocumentBuilderFactory。由于其他限制,我无法升级到 jdk8。

到目前为止,我还没有运气;所有搜索都返回上面链接中显示的相同代码。

可以这样做吗?

【问题讨论】:

    标签: java xml dom document


    【解决方案1】:

    这很难做到,但由于您的实际问题是 安全漏洞 而不是 TransformerFactory,这可能是一个更好的方法。

    您应该能够将TransformerFactory 配置为忽略实体以防止此类问题。见:Preventing XXE Injection

    另一个可能对您的安全问题有用的方法是使用TransformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING)。这应该可以防止您担心的问题。另见this forum thread on coderanch.

    【讨论】:

    • 我们可以在 TransformerFactory 上设置 FEATURE_SECURE_PROCESSING。但是,我们不能设置 ACCESS_EXTERNAL_DTD、ACCESS_EXTERNAL_SCHEMA 也是需要的。在 JDK 8 中通过设置 FEATURE_SECURE_PROCESSING 会自动设置其他 2 个特性。 JDK 6 和 JDK 7 将不支持这些功能,这使其成为不完整的解决方案。
    • @iranichai 他们不包含在 Java 7 中吗?文档似乎表明它们是
    • 我看到异常'javax.xml.transform.TransformerConfigurationException:无法在此 TransformerFactory 上设置功能'javax.xml.XMLConstants/property/accessExternalDTD'。用 jdk7 发现这个stackoverflow.com/questions/27128578/…
    • 同时进行搜索会显示此错误报告bugs.java.com/bugdatabase/view_bug.do?bug_id=8016153,其中表示该问题已在 jdk8 中修复,并且 jdk7u40 的受影响版本
    【解决方案2】:

    设置FEATURE_SECURE_PROCESSING 可能有帮助也可能没有帮助,这取决于TransformerFactory.getInstance() 实际返回的实现。

    例如在 Java 7 中,在类路径上没有额外的 XML 库设置 transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 没有帮助。

    您可以通过提供StreamSource 以外的Source 来解决此问题(哪个工厂需要使用您无法控制的一些 设置进行解析)。

    例如,您可以像这样使用StAXSource:

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); // does not help in Java 7
    Transformer transformer = transformerFactory.newTransformer();
    
    // StreamSource is insecure by default:
    // Source source = new StreamSource(new StringReader(xxeXml));
    
    // Source configured to be secure:
    XMLInputFactory xif = XMLInputFactory.newFactory();
    xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
    xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
    XMLEventReader xmlEventReader = xif.createXMLEventReader(new StringReader(xxeXml));
    Source source = new StAXSource(xmlEventReader);
    
    transformer.transform(
            source,
            new StreamResult(new ByteArrayOutputStream()));
    

    注意实际的TrasformerFactory 可能实际上并不支持StAXSource,因此您需要使用类路径测试您的代码,就像在生产环境中一样。例如,Saxon 9(旧的,我知道)不支持 StAXSource,而我知道的唯一“修复”它的干净方法是提供自定义 net.sf.saxon.Configuration 实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 2014-03-12
      相关资源
      最近更新 更多