XWiki Platform users may execute anything with superadmin right through comments and async macro
Description
XWiki Platform is a generic wiki platform. Starting in version 11.6-rc-1, comments are supposed to be executed with the right of superadmin but in restricted mode (anything dangerous is disabled), but the async macro does not take into account the restricted mode. This means that any user with comment right can use the async macro to make it execute any wiki content with the right of superadmin. This has been patched in XWiki 14.9, 14.4.6, and 13.10.10. The only known workaround consists of applying a patch and rebuilding and redeploying org.xwiki.platform:xwiki-platform-rendering-async-macro.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.platform:xwiki-platform-rendering-async-macroMaven | >= 11.6-rc-1, < 13.10.10 | 13.10.10 |
org.xwiki.platform:xwiki-platform-rendering-async-macroMaven | >= 14.0, < 14.4.6 | 14.4.6 |
org.xwiki.platform:xwiki-platform-rendering-async-macroMaven | >= 14.5, < 14.9 | 14.9 |
Affected products
1- Range: >= 11.6-rc-1, < 13.10.10
Patches
100532d9f1404XWIKI-20234: It's possible to execute anything with superadmin right through comments and async macro
6 files changed · +151 −4
xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-async/xwiki-platform-rendering-async-api/src/main/java/org/xwiki/rendering/async/internal/block/BlockAsyncRendererConfiguration.java+24 −0 modified@@ -61,6 +61,8 @@ public class BlockAsyncRendererConfiguration extends AsyncRendererConfiguration private boolean inline; + private boolean resricted; + private BlockAsyncRendererDecorator decorator; private Set<EntityReference> references; @@ -238,6 +240,28 @@ public void setInline(boolean inline) this.inline = inline; } + /** + * @return indicator of whether the transformation context is restricted or not + * @since 14.9 + * @since 14.4.6 + * @since 13.10.10 + */ + public boolean isResricted() + { + return this.resricted; + } + + /** + * @param resricted indicator of whether the transformation context is restricted or not + * @since 14.9 + * @since 14.4.6 + * @since 13.10.10 + */ + public void setResricted(boolean resricted) + { + this.resricted = resricted; + } + /** * @return the decorator */
xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-async/xwiki-platform-rendering-async-api/src/main/java/org/xwiki/rendering/async/internal/block/DefaultBlockAsyncRenderer.java+1 −1 modified@@ -147,7 +147,7 @@ public Block execute(boolean async, boolean cached) throws RenderingException private Block tranform(XDOM xdom, Block block) throws RenderingException { TransformationContext transformationContext = - new TransformationContext(xdom, this.configuration.getDefaultSyntax(), false); + new TransformationContext(xdom, this.configuration.getDefaultSyntax(), this.configuration.isResricted()); transformationContext.setTargetSyntax(this.configuration.getTargetSyntax()); transformationContext.setId(this.configuration.getTransformationId());
xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-async/xwiki-platform-rendering-async-macro/src/main/java/org/xwiki/rendering/async/internal/AbstractExecutedContentMacro.java+3 −0 modified@@ -142,6 +142,9 @@ protected BlockAsyncRendererConfiguration createBlockAsyncRendererConfiguration( // Set the transformation id configuration.setTransformationId(context.getTransformationContext().getId()); + // Indicate if we are in a restricted mode + configuration.setResricted(context.getTransformationContext().isRestricted()); + return configuration; } }
xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-async/xwiki-platform-rendering-async-macro/src/test/java/org/xwiki/rendering/async/AsyncMacroTest.java+107 −0 added@@ -0,0 +1,107 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.xwiki.rendering.async; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.xwiki.rendering.async.internal.AsyncMacro; +import org.xwiki.rendering.async.internal.block.BlockAsyncRendererConfiguration; +import org.xwiki.rendering.async.internal.block.BlockAsyncRendererExecutor; +import org.xwiki.rendering.block.MacroBlock; +import org.xwiki.rendering.block.WordBlock; +import org.xwiki.rendering.block.XDOM; +import org.xwiki.rendering.listener.MetaData; +import org.xwiki.rendering.macro.MacroContentParser; +import org.xwiki.rendering.syntax.Syntax; +import org.xwiki.rendering.transformation.MacroTransformationContext; +import org.xwiki.test.TestEnvironment; +import org.xwiki.test.annotation.ComponentList; +import org.xwiki.test.junit5.mockito.ComponentTest; +import org.xwiki.test.junit5.mockito.InjectComponentManager; +import org.xwiki.test.junit5.mockito.InjectMockComponents; +import org.xwiki.test.junit5.mockito.MockComponent; +import org.xwiki.test.mockito.MockitoComponentManager; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Unit tests for {@link AsyncMacro}. + * + * @version $Id$ + * @since 8.3RC1 + */ +@ComponentTest +@ComponentList(TestEnvironment.class) +class AsyncMacroTest +{ + @InjectMockComponents + private AsyncMacro macro; + + @InjectComponentManager + private MockitoComponentManager componentManager; + + @MockComponent + private MacroContentParser parser; + + private BlockAsyncRendererExecutor executor; + + @BeforeEach + public void beforeEach() throws Exception + { + this.executor = this.componentManager.getInstance(BlockAsyncRendererExecutor.class); + } + + @Test + void executeInRestrictedMode() throws Exception + { + MacroBlock macroBlock = new MacroBlock("async", Collections.<String, String>emptyMap(), false); + MetaData metadata = new MetaData(); + metadata.addMetaData(MetaData.SOURCE, "source"); + XDOM pageXDOM = new XDOM(Arrays.asList(macroBlock), metadata); + MacroTransformationContext macroContext = new MacroTransformationContext(); + macroContext.setSyntax(Syntax.XWIKI_2_0); + macroContext.setCurrentMacroBlock(macroBlock); + macroContext.setXDOM(pageXDOM); + macroContext.getTransformationContext().setRestricted(true); + + XDOM contentXDOM = new XDOM(Arrays.asList(new WordBlock("test")), metadata); + when(this.parser.parse(eq(""), same(macroContext), eq(false), eq(false))).thenReturn(contentXDOM); + + when(this.executor.execute(any())).thenReturn(new WordBlock("result")); + + this.macro.execute(new AsyncMacroParameters(), "", macroContext); + + ArgumentCaptor<BlockAsyncRendererConfiguration> configurationCaptor = + ArgumentCaptor.forClass(BlockAsyncRendererConfiguration.class); + verify(this.executor).execute(configurationCaptor.capture()); + + BlockAsyncRendererConfiguration configuration = configurationCaptor.getValue(); + assertTrue(configuration.isResricted()); + } +}
xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-async/xwiki-platform-rendering-async-macro/src/test/java/org/xwiki/rendering/async/IntegrationTests.java+1 −2 renamed@@ -17,7 +17,7 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -package org.xwiki.rendering.macro.box; +package org.xwiki.rendering.async; import java.util.List; @@ -33,7 +33,6 @@ import org.xwiki.model.reference.EntityReference; import org.xwiki.observation.ObservationManager; import org.xwiki.observation.event.Event; -import org.xwiki.rendering.async.AsyncContext; import org.xwiki.rendering.async.internal.AsyncRendererJobRequest; import org.xwiki.rendering.async.internal.AsyncRendererJobStatus; import org.xwiki.rendering.test.integration.RenderingTestSuite;
xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-macros/xwiki-platform-rendering-macro-context/src/test/java/org/xwiki/rendering/internal/macro/context/ContextMacroTest.java+15 −1 modified@@ -162,6 +162,17 @@ void executeWithReferencedDocumentNotViewableByTheAuthor() throws Exception @Test void executeOk() throws Exception + { + execute(false); + } + + @Test + void executeInRestrictedMode() throws Exception + { + execute(true); + } + + private void execute(boolean restricted) throws Exception { MacroBlock macroBlock = new MacroBlock("context", Collections.<String, String>emptyMap(), false); MetaData metadata = new MetaData(); @@ -171,12 +182,14 @@ void executeOk() throws Exception macroContext.setSyntax(Syntax.XWIKI_2_0); macroContext.setCurrentMacroBlock(macroBlock); macroContext.setXDOM(pageXDOM); + macroContext.getTransformationContext().setRestricted(restricted); DocumentModelBridge dmb = mock(DocumentModelBridge.class); when(this.dab.getTranslatedDocumentInstance(TARGET_REFERENCE)).thenReturn(dmb); XDOM contentXDOM = new XDOM(Arrays.asList(new WordBlock("test")), metadata); - when(this.parser.parse(eq(""), same(macroContext), eq(false), any(MetaData.class), eq(false))).thenReturn(contentXDOM); + when(this.parser.parse(eq(""), same(macroContext), eq(false), any(MetaData.class), eq(false))) + .thenReturn(contentXDOM); ContextMacroParameters parameters = new ContextMacroParameters(); parameters.setDocument("target"); @@ -193,5 +206,6 @@ void executeOk() throws Exception assertEquals(AUTHOR, configuration.getSecureAuthorReference()); assertEquals(SOURCE_REFERENCE, configuration.getSecureDocumentReference()); assertSame(pageXDOM, configuration.getXDOM()); + assertEquals(restricted, configuration.isResricted()); } }
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
5- github.com/advisories/GHSA-9cqm-5wf7-wcj7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-26471ghsaADVISORY
- github.com/xwiki/xwiki-platform/commit/00532d9f1404287cf3ec3a05056640d809516006ghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-platform/security/advisories/GHSA-9cqm-5wf7-wcj7ghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XWIKI-20234ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.