Privilege escalation in Xwiki platform
Description
XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. In affected versions it's possible for a user to write a script in which any velocity content is executed with the right of any other document content author. Since this API require programming right and the user does not have it, the expected result is $doc.document.authors.contentAuthor (not executed script), unfortunately with the security vulnerability it is possible for the attacker to get XWiki.superadmin which shows that the title was executed with the right of the unmodified document. This has been patched in XWiki versions 14.10.7 and 15.2RC1. Users are advised to upgrade. There are no known workarounds for this vulnerability.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.xwiki.platform:xwiki-platform-display-apiMaven | >= 3.2-milestone-3, < 14.10.7 | 14.10.7 |
org.xwiki.platform:xwiki-platform-display-apiMaven | >= 15.0, < 15.2-rc-1 | 15.2-rc-1 |
Affected products
1- Range: >= 3.2-milestone-3, < 14.10.7
Patches
211a9170dfe63XWIKI-20624: Improve title display for modified documents
4 files changed · +86 −6
xwiki-platform-core/xwiki-platform-display/xwiki-platform-display-api/src/main/java/org/xwiki/display/internal/AbstractDocumentTitleDisplayer.java+5 −5 modified@@ -176,7 +176,7 @@ private XDOM displayTitle(DocumentModelBridge document, DocumentDisplayerParamet // Evaluate the title only if the document has script rights, otherwise use the raw title. if (authorizationManager.hasAccess(Right.SCRIPT, document.getContentAuthorReference(), document.getDocumentReference())) { - title = evaluateTitle(rawTitle, document.getDocumentReference(), parameters); + title = evaluateTitle(rawTitle, document, parameters); } return parseTitle(title); } catch (Exception e) { @@ -226,12 +226,12 @@ protected XDOM parseTitle(String title) * @param parameters display parameters * @return the result of evaluating the Velocity script from the given title */ - protected String evaluateTitle(String title, DocumentReference documentReference, + protected String evaluateTitle(String title, DocumentModelBridge document, DocumentDisplayerParameters parameters) { StringWriter writer = new StringWriter(); String namespace = defaultEntityReferenceSerializer.serialize(parameters.isTransformationContextIsolated() - ? documentReference : documentAccessBridge.getCurrentDocumentReference()); + ? document.getDocumentReference() : documentAccessBridge.getCurrentDocumentReference()); // Get the velocity engine VelocityEngine velocityEngine; @@ -249,11 +249,11 @@ protected String evaluateTitle(String title, DocumentReference documentReference if (parameters.isExecutionContextIsolated()) { backupObjects = new HashMap<>(); // The following method call also clones the execution context. - documentAccessBridge.pushDocumentInContext(backupObjects, documentReference); + documentAccessBridge.pushDocumentInContext(backupObjects, document); // Pop the document from the context only if the push was successful! canPop = true; // Make sure to synchronize the context wiki with the context document's wiki. - modelContext.setCurrentEntityReference(documentReference.getWikiReference()); + modelContext.setCurrentEntityReference(document.getDocumentReference().getWikiReference()); } velocityEngine.evaluate(velocityManager.getVelocityContext(), writer, namespace, title); } catch (Exception e) {
xwiki-platform-core/xwiki-platform-display/xwiki-platform-display-api/src/test/java/org/xwiki/display/internal/DocumentTitleDisplayerTest.java+2 −1 modified@@ -51,6 +51,7 @@ import static org.junit.Assert.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -134,7 +135,7 @@ public void whenSettingTheContextDocumentTheContextWikiIsAlsoSet() throws Except this.mocker.getComponentUnderTest().display(document, params); // Check that the context is set. - verify(dab).pushDocumentInContext(any(), eq(documentReference)); + verify(dab).pushDocumentInContext(any(), same(document)); verify(modelContext).setCurrentEntityReference(documentReference.getWikiReference()); // Check that the context is restored.
xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/AllITs.java+6 −0 modified@@ -188,4 +188,10 @@ class NestedTextAreaIT extends TextAreaIT class NestedSheetIT extends SheetIT { } + + @Nested + @DisplayName("Script author Tests") + class NestedScriptAuthorIT extends ScriptAuthorIT + { + } }
xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/ScriptAuthorIT.java+73 −0 added@@ -0,0 +1,73 @@ +/* + * 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.flamingo.test.docker; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.xwiki.model.reference.DocumentReference; +import org.xwiki.test.docker.junit5.TestReference; +import org.xwiki.test.docker.junit5.UITest; +import org.xwiki.test.ui.TestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Make sure a script end up being executed by the right author in various use cases. + * + * @version $Id$ + */ +@UITest +class ScriptAuthorIT +{ + @BeforeAll + public void setup(TestUtils setup) + { + setup.loginAsSuperAdmin(); + } + + @Test + @Order(1) + void renderTitleInModifiedDocument(TestUtils setup, TestReference reference) throws Exception + { + // Give a page programming right + setup.loginAsSuperAdmin(); + DocumentReference programmingReference = reference; + setup.rest().savePage(programmingReference); + + // Write a script without programming right + setup.createUser("renderTitleInModifiedDocument", "renderTitleInModifiedDocument", null); + setup.setGlobalRights(null, "renderTitleInModifiedDocument", "script", true); + setup.login("renderTitleInModifiedDocument", "renderTitleInModifiedDocument"); + DocumentReference scriptReference = + new DocumentReference("Script", programmingReference.getLastSpaceReference()); + StringBuilder source = new StringBuilder(); + source.append("{{velocity}}\n"); + source.append("#set($main = $xwiki.getDocument('" + setup.serializeReference(programmingReference) + "'))\n"); + source.append("$main.setTitle('$doc.document.authors.contentAuthor')\n"); + source.append("$main.getPlainTitle()\n"); + source.append("{{/velocity}}"); + setup.rest().savePage(scriptReference, source.toString(), "sheet title"); + + StringBuilder result = new StringBuilder(); + result.append("<p>$doc.document.authors.contentAuthor</p>"); + assertEquals(result.toString(), setup.executeAndGetBodyAsString(scriptReference, null)); + } +}
41d7dca2d300XWIKI-20625: Improve document title display in the document tree
1 file changed · +0 −4
xwiki-platform-core/xwiki-platform-index/xwiki-platform-index-tree/xwiki-platform-index-tree-macro/src/main/resources/XWiki/DocumentTreeMacros.xml+0 −4 modified@@ -354,10 +354,6 @@ #if ($canViewDoc && $docTreeConfig.showDocumentTitle) ## Display the translated title. #set ($translatedDocument = $xwiki.getDocument($documentReference).translatedDocument) - ## Make sure the displayed title is not affected by the sheet request parameter (e.g. when $translatedDocument is - ## the current document). By setting the title (even if we don't change it) the internal document instance is cloned - ## so it's going to be different than the current document instance (which is the target of the sheet parameter). - #set ($discard = $translatedDocument.setTitle($translatedDocument.title)) #set ($plainTitle = $translatedDocument.plainTitle) #if (!$stringtool.isBlank($plainTitle)) #set ($label = $plainTitle)
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
7- github.com/advisories/GHSA-rmxw-c48h-2vf5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-46244ghsaADVISORY
- github.com/xwiki/xwiki-platform/commit/11a9170dfe63e59f4066db67f84dbfce4ed619c6ghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-platform/commit/41d7dca2d30084966ca6a7ee537f39ee8354a7e3ghsax_refsource_MISCWEB
- github.com/xwiki/xwiki-platform/security/advisories/GHSA-rmxw-c48h-2vf5ghsax_refsource_CONFIRMWEB
- jira.xwiki.org/browse/XWIKI-20624ghsax_refsource_MISCWEB
- jira.xwiki.org/browse/XWIKI-20625ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.