CVE-2022-24898 (Java, published 2022-04-28T20:15Z)
Description: value: org.xwiki.commons:xwiki-commons-xml is a common module used by other XWiki top level projects. Starting in version 2.7 and prior to versions 12.10.10, 13.4.4, and 13.8-rc-1, it is possible for a script to access any file accessing to the user running XWiki application server with XML External Entity Injection through the XML script service. The problem has been patched in versions 12.10.10, 13.4.4, and 13.8-rc-1. There is no easy workaround for fixing this vulnerability other than upgrading and being careful when giving Script rights.
Severity: MEDIUM (CVSS v3 base score: 4.9)
Weakness: CWE-611 \u2014 Improper Restriction of XML External Entity Reference
The product processes an XML document that can contain XML entities with URIs that resolve to documents outside of the intended sphere of control, causing the product to embed incorrect documents into its output.
Repository: https://github.com/xwiki/xwiki-commons
Files changed:
xwiki-commons-core/xwiki-commons-xml/src/main/java/org/xwiki/xml/XMLUtils.java
xwiki-commons-core/xwiki-commons-xml/src/test/java/org/xwiki/xml/XMLUtilsTest.java
Commit message: XWIKI-18946: Improve the default XML parser


Vulnerable code:

Fixed code:
    /** Xerces configuration parameter for prevent DOCTYPE definition. */
    private static final String DISABLE_EXTERNAL_DOCTYPE_DECLARATION =
        "http://apache.org/xml/features/disallow-doctype-decl";

    /** Xerces configuration parameter for disabling inserting entities defined in external files. */
    private static final String DISABLE_EXTERNAL_PARAMETER_ENTITIES =
        "http://xml.org/sax/features/external-parameter-entities";

    /** Xerces configuration parameter for disabling inserting entities defined in external files. */
    private static final String DISABLE_EXTERNAL_GENERAL_ENTITIES =
        "http://xml.org/sax/features/external-general-entities";


            // Avoid XML eXternal Entity injection (XXE)
            if (p.getDomConfig().canSetParameter(DISABLE_EXTERNAL_DOCTYPE_DECLARATION, false)) {
                p.getDomConfig().setParameter(DISABLE_EXTERNAL_DOCTYPE_DECLARATION, false);
            }
            if (p.getDomConfig().canSetParameter(DISABLE_EXTERNAL_PARAMETER_ENTITIES, false)) {
                p.getDomConfig().setParameter(DISABLE_EXTERNAL_PARAMETER_ENTITIES, false);
            }
            if (p.getDomConfig().canSetParameter(DISABLE_EXTERNAL_GENERAL_ENTITIES, false)) {
                p.getDomConfig().setParameter(DISABLE_EXTERNAL_GENERAL_ENTITIES, false);
            }
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.apache.commons.io.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;

    @Test
    void disableExternalEntities()
        throws ClassNotFoundException, InstantiationException, IllegalAccessException, ClassCastException, IOException
    {
        File tempFile = File.createTempFile("file", ".txt");

        FileUtils.write(tempFile, "external", StandardCharsets.UTF_8);

        DOMImplementationLS ls =
            (DOMImplementationLS) DOMImplementationRegistry.newInstance().getDOMImplementation("LS 3.0");
        LSInput input = ls.createLSInput();
        input.setStringData("<?xml version='1.0' encoding='UTF-8'?>" + "<!DOCTYPE root[<!ENTITY xxe SYSTEM 'file://"
            + tempFile.getAbsolutePath() + "' >]><root>&xxe;</root>");

        Document result = XMLUtils.parse(input);
        assertNotEquals("external", result.getDocumentElement().getTextContent());
    }