Arbitrary file access through XML parsing in org.xwiki.commons:xwiki-commons-xml
Description
An XXE vulnerability in XWiki Commons XML script service allows authenticated scripts to read arbitrary files accessible to the application server.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
An XXE vulnerability in XWiki Commons XML script service allows authenticated scripts to read arbitrary files accessible to the application server.
Vulnerability
Starting in version 2.7 and prior to versions 12.10.10, 13.4.4, and 13.8-rc-1, org.xwiki.commons:xwiki-commons-xml does not disable external entity processing in its default XML parser. This allows XML External Entity (XXE) injection through the XML script service [1][3]. The affected class XMLUtils lacked settings to disallow DOCTYPE declarations and external parameter/general entities [2]. Versions 2.7 up to (but not including) 12.10.10, 13.4.4, and 13.8-rc-1 are vulnerable.
Exploitation
An attacker with Script rights on the XWiki instance can craft a malicious XML payload containing an external entity reference to a file on the server (e.g., file:///etc/passwd). Using the $xml.parse() service, the script triggers the parser to fetch and include the file content, which can then be serialized and output [3]. No additional authentication or network position is required beyond the ability to execute Velocity or similar scripts.
Impact
Successful exploitation results in arbitrary file disclosure: any file that the user running the XWiki application server can read becomes accessible to the attacker. The confidentiality of sensitive data (e.g., configuration, passwords, user data) is compromised, potentially leading to further system compromise [1][3].
Mitigation
The vulnerability is fixed in versions 12.10.10, 13.4.4, and 13.8-rc-1 [1][2][3]. The patch adds Xerces configuration parameters to disallow DOCTYPE declarations and disable external parameter/general entities [2]. There is no easy workaround; the only recommended action is to upgrade and, as a general practice, be careful when granting Script rights [3].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.commons:xwiki-commons-xmlMaven | >= 2.7, < 12.10.10 | 12.10.10 |
org.xwiki.commons:xwiki-commons-xmlMaven | >= 13.0.0, < 13.4.4 | 13.4.4 |
org.xwiki.commons:xwiki-commons-xmlMaven | >= 13.5-rc-1, < 13.8-rc-1 | 13.8-rc-1 |
Affected products
2- Range: >= 2.7, < 12.10.10
Patches
1947e8921ebd9XWIKI-18946: Improve the default XML parser
2 files changed · +50 −0
xwiki-commons-core/xwiki-commons-xml/src/main/java/org/xwiki/xml/XMLUtils.java+23 −0 modified@@ -110,6 +110,18 @@ public final class XMLUtils /** Xerces configuration parameter for disabling fetching and checking XMLs against their DTD. */ private static final String DISABLE_DTD_PARAM = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; + /** 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"; + static { DOMImplementationLS implementation = null; try { @@ -516,6 +528,17 @@ public static Document parse(LSInput source) if (p.getDomConfig().canSetParameter(DISABLE_DTD_PARAM, false)) { p.getDomConfig().setParameter(DISABLE_DTD_PARAM, false); } + + // 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); + } return p.parse(source); } catch (Exception ex) { LOGGER.warn("Cannot parse XML document: [{}]", ex.getMessage());
xwiki-commons-core/xwiki-commons-xml/src/test/java/org/xwiki/xml/XMLUtilsTest.java+27 −0 modified@@ -19,10 +19,19 @@ */ package org.xwiki.xml; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.io.FileUtils; import org.apache.html.dom.HTMLDocumentImpl; import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.html.HTMLElement; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSInput; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -279,4 +288,22 @@ void serializeNode() serialize = XMLUtils.serialize(node, false); assertEquals("<HTML><HEAD/><BODY class=\"toto\"/></HTML>", serialize); } + + @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()); + } }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-m2r5-4w96-qxg5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-24898ghsaADVISORY
- github.com/xwiki/xwiki-commons/commit/947e8921ebd95462d5a7928f397dd1b64f77c7d5ghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-commons/security/advisories/GHSA-m2r5-4w96-qxg5ghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XWIKI-18946ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.