在 Java 代码中加载 XSLT 并安全地解析它

问题描述 投票:0回答:0

如何解决以下代码中的声纳问题

import org.springframework.core.io.ClassPathResource;
import org.xml.sax.InputSource;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;
import java.io.StringWriter;

public class XmlUtility {

  public static String removeNamespaceAndReturnChildElement(String xmlString, String xmlTagName) {
    var transformerFactory = TransformerFactory.newInstance();
    transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
    transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
    transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

    StreamSource namespaceRemoverXslt = new StreamSource(new ClassPathResource("/namespaceRemover.xslt").getFile());

    var transformer = transformerFactory.newTransformer(namespaceRemoverXslt); //NON-Compliant - Security - A malicious XSLT could be provided
    StringWriter xmlTagNameBufferWithoutNamespace = new StringWriter();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.transform(new StreamSource(xmlString), new StreamResult(xmlTagNameBufferWithoutNamespace));

    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
    documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    documentBuilderFactory.setXIncludeAware(false);
    documentBuilderFactory.setExpandEntityReferences(false);
    documentBuilderFactory.setValidating(true); //NON-Compliant - XML parsers should not load external schemas
    var documentBuilder = documentBuilderFactory.newDocumentBuilder();
    var inputSource = new InputSource(new StringReader(xmlTagNameBufferWithoutNamespace.toString()));
    org.w3c.dom.Document xmlDocument = documentBuilder.parse(inputSource);

    var deliveryNode = xmlDocument.getElementsByTagName(xmlTagName).item(0);
    StringWriter bufferFirstXmlElement = new StringWriter();
    transformer.transform(new DOMSource(deliveryNode), new StreamResult(bufferFirstXmlElement));
    return bufferFirstXmlElement.toString();
  }
}

var transformer = transformerFactory.newTransformer(namespaceRemoverXslt);
行中,即使我在变压器工厂中启用了安全功能处理,Sonar 仍会抱怨错误“安全性 - 可能会提供恶意 XSLT”。我听说如果我的应用程序有一些其他依赖项,如 hibernate-core,那么声纳可能会显示此类错误。

documentBuilderFactory.setValidating(true)
行中声纳抱怨错误“XML 解析器不应加载外部模式”。如果我删除它,那么 Semgrep 会给出错误“代码无法在解析 XML 之前启用验证,即 documentBuilder.parse(inputSource),这让攻击者有机会提供恶意输入”。

我正在从我的类路径加载 xslt,所以我信任 xslt。

java xslt sonarqube semgrep
© www.soinside.com 2019 - 2024. All rights reserved.