XWiki Rendering is vulnerable to RCE attacks when processing nested macros
Description
XWiki Rendering is a generic rendering system that converts textual input in a given syntax (wiki syntax, HTML, etc) into another syntax (XHTML, etc). Starting in version 4.2-milestone-1 and prior to versions 13.10.11, 14.4.7, and 14.10, the default macro content parser doesn't preserve the restricted attribute of the transformation context when executing nested macros. This allows executing macros that are normally forbidden in restricted mode, in particular script macros. The cache and chart macros that are bundled in XWiki use the vulnerable feature. This has been patched in XWiki 13.10.11, 14.4.7 and 14.10. To avoid the exploitation of this bug, comments can be disabled for untrusted users until an upgrade to a patched version has been performed. Note that users with edit rights will still be able to add comments via the object editor even if comments have been disabled.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.rendering:xwiki-rendering-transformation-macroMaven | >= 4.2-milestone-1, < 13.10.11 | 13.10.11 |
org.xwiki.rendering:xwiki-rendering-transformation-macroMaven | >= 14.0, < 14.4.7 | 14.4.7 |
org.xwiki.rendering:xwiki-rendering-transformation-macroMaven | >= 14.5, < 14.10 | 14.10 |
Affected products
1- Range: >= 4.2-milestone-1, < 13.10.11
Patches
1c73fa3ccd4acXRENDERING-689: Default macro content parser doesn't preserve restricted contexts
2 files changed · +25 −2
xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParser.java+3 −1 modified@@ -129,7 +129,9 @@ private XDOM createXDOM(String content, MacroTransformationContext macroContext, // Execute the content if (transform && macroContext.getTransformation() != null) { - TransformationContext txContext = new TransformationContext(result, syntax); + TransformationContext wrappingContext = macroContext.getTransformationContext(); + boolean isRestricted = wrappingContext != null && wrappingContext.isRestricted(); + TransformationContext txContext = new TransformationContext(result, syntax, isRestricted); txContext.setId(macroContext.getId()); performTransformation((MutableRenderingContext) this.renderingContext, macroContext.getTransformation(), txContext, result);
xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/test/java/org/xwiki/rendering/internal/macro/DefaultMacroContentParserTest.java+22 −1 modified@@ -39,13 +39,15 @@ import org.xwiki.rendering.transformation.MacroTransformationContext; import org.xwiki.rendering.transformation.RenderingContext; import org.xwiki.rendering.transformation.Transformation; +import org.xwiki.rendering.transformation.TransformationContext; import org.xwiki.test.annotation.ComponentList; import org.xwiki.test.junit5.mockito.ComponentTest; import org.xwiki.test.junit5.mockito.InjectMockComponents; import org.xwiki.test.junit5.mockito.MockComponent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -108,7 +110,26 @@ void parseInlineWithStandaloneMacroWithTransformations() throws Exception this.macroContentParser.parse("content", this.macroContext, true, true); - verify((MutableRenderingContext) this.renderingContext).transformInContext(any(), any(), + verify((MutableRenderingContext) this.renderingContext).transformInContext(any(), + argThat(context -> !context.isRestricted()), eq(new XDOM(Arrays.<Block>asList(new MacroBlock("macro", Collections.emptyMap(), null, true))))); } + + @Test + void parseInlineWithStandaloneMacroWithRestrictedTransformations() throws Exception + { + when(this.mockParser.parse(any(Reader.class))) + .thenReturn( + new XDOM(Collections.singletonList(new MacroBlock("macro", Collections.emptyMap(), null, false)))); + + this.macroContext.setTransformation(mock(Transformation.class)); + this.macroContext.getTransformationContext().setRestricted(true); + + this.macroContentParser.parse("content", this.macroContext, true, true); + + verify((MutableRenderingContext) this.renderingContext).transformInContext( + any(), argThat(TransformationContext::isRestricted), + eq(new XDOM(Collections.singletonList(new MacroBlock("macro", Collections.emptyMap(), null, true)))) + ); + } }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-32mf-57h2-64x9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-53836ghsaADVISORY
- github.com/xwiki/xwiki-rendering/commit/c73fa3ccd4ac59057e48e5d4325f659e78e8f86dghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-rendering/security/advisories/GHSA-32mf-57h2-64x9ghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XRENDERING-689ghsax_refsource_MISCWEB
- jira.xwiki.org/browse/XWIKI-20375ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.