CVE-2023-46244 (published 2023-11-07T19:15Z)

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.

CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-863
cwe_name: Incorrect Authorization
description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are incorrectly applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/xwiki/xwiki-platform
commit_details: repo_url: https://github.com/xwiki/xwiki-platform
author: Thomas Mortagne
author_date: 2023-03-09 17:19:11+01:00
msg: XWIKI-20624: Improve title display for modified documents
repository: repo_url: https://github.com/xwiki/xwiki-platform
repo_name: xwiki/xwiki-platform
description: The XWiki platform
repo_language: Java
owner: xwiki
file_changes: filename: AbstractDocumentTitleDisplayer.java
change_type: ModificationType.MODIFY
diff: @@ -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) {

programming_language: Java
filename: DocumentTitleDisplayerTest.java
change_type: ModificationType.MODIFY
diff: @@ -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.

programming_language: Java
filename: AllITs.java
change_type: ModificationType.MODIFY
diff: @@ -188,4 +188,10 @@ class NestedTextAreaIT extends TextAreaIT
     class NestedSheetIT extends SheetIT
     {
     }
+
+    @Nested
+    @DisplayName("Script author Tests")
+    class NestedScriptAuthorIT extends ScriptAuthorIT
+    {
+    }
 }

programming_language: Scala
filename: ScriptAuthorIT.java
change_type: ModificationType.ADD
diff: @@ -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));
+    }
+}

programming_language: Java
repo_url: https://github.com/xwiki/xwiki-platform
commit_details: repo_url: https://github.com/xwiki/xwiki-platform
author: Thomas Mortagne
author_date: 2023-03-08 16:49:30+01:00
msg: XWIKI-20625: Improve document title display in the document tree
repository: repo_url: https://github.com/xwiki/xwiki-platform
repo_name: xwiki/xwiki-platform
description: The XWiki platform
repo_language: Java
owner: xwiki
file_changes: filename: DocumentTreeMacros.xml
change_type: ModificationType.MODIFY
diff: @@ -354,10 +354,6 @@
   #if ($canViewDoc &amp;&amp; $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)

programming_language: PowerShell