VYPR
High severityNVD Advisory· Published Jun 20, 2023· Updated Dec 6, 2024

Privilege escalation (PR) from account through TipsPanel

CVE-2023-35166

Description

XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. It's possible to execute any wiki content with the right of the TipsPanel author by creating a tip UI extension. This has been patched in XWiki 15.1-rc-1 and 14.10.5.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-help-uiMaven
>= 8.1-milestone-1, < 14.10.514.10.5
org.xwiki.platform:xwiki-platform-help-uiMaven
>= 15.0-rc-1, < 15.1-rc-115.1-rc-1

Affected products

1

Patches

1
98208c5bb1e8

XWIKI-20281: Improve tips rendering

https://github.com/xwiki/xwiki-platformThomas MortagneFeb 1, 2023via ghsa
8 files changed · +365 10
  • xwiki-platform-core/xwiki-platform-help/pom.xml+8 0 modified
    @@ -34,4 +34,12 @@
       <modules>
         <module>xwiki-platform-help-ui</module>
       </modules>
    +  <profiles>
    +    <profile>
    +      <id>integration-tests</id>
    +      <modules>
    +        <module>xwiki-platform-help-test</module>
    +      </modules>
    +    </profile>
    +  </profiles>
     </project>
    
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-test/pom.xml+48 0 added
    @@ -0,0 +1,48 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +
    +<!--
    + * 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.
    +-->
    +
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +  <modelVersion>4.0.0</modelVersion>
    +  <parent>
    +    <groupId>org.xwiki.platform</groupId>
    +    <artifactId>xwiki-platform-help</artifactId>
    +    <version>15.1-SNAPSHOT</version>
    +  </parent>
    +  <artifactId>xwiki-platform-help-test</artifactId>
    +  <name>XWiki Platform - Panels - Help - Parent POM</name>
    +  <packaging>pom</packaging>
    +  <description>XWiki Platform - Help - Tests - Parent POM</description>
    +  <properties>
    +    <!-- Don't run backward-compatibility checks in test modules since we don't consider them as public APIs -->
    +    <xwiki.revapi.skip>true</xwiki.revapi.skip>
    +    <!-- Don't run Checkstyle in test modules -->
    +    <xwiki.checkstyle.skip>true</xwiki.checkstyle.skip>
    +  </properties>
    +  <profiles>
    +    <profile>
    +      <id>docker</id>
    +      <modules>
    +        <module>xwiki-platform-panels-test-docker</module>
    +      </modules>
    +    </profile>
    +  </profiles>
    +</project>
    
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-test/xwiki-platform-help-test-docker/pom.xml+116 0 added
    @@ -0,0 +1,116 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +
    +<!--
    + * 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.
    +-->
    +
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    +  <parent>
    +    <artifactId>xwiki-platform-help-test</artifactId>
    +    <groupId>org.xwiki.platform</groupId>
    +    <version>15.1-SNAPSHOT</version>
    +  </parent>
    +  <modelVersion>4.0.0</modelVersion>
    +  <artifactId>xwiki-platform-help-test-docker</artifactId>
    +  <!-- TODO: Move to use "functional-test" in the future when http://jira.codehaus.org/browse/MNG-1911 is fixed,
    +       see https://jira.xwiki.org/browse/XWIKI-7683 -->
    +  <packaging>jar</packaging>
    +  <name>XWiki Platform - Help - Tests - Functional Docker Tests</name>
    +  <description>XWiki Platform - Help - Tests - Functional Tests in Docker</description>
    +  <properties>
    +    <!-- Functional tests are allowed to output content to the console -->
    +    <xwiki.surefire.captureconsole.skip>true</xwiki.surefire.captureconsole.skip>
    +  </properties>
    +  <dependencies>
    +    <!-- =========================================
    +         Runtime Dependencies for tested features.
    +         ========================================= -->
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-help-ui</artifactId>
    +      <version>${project.version}</version>
    +      <scope>runtime</scope>
    +      <type>xar</type>
    +    </dependency>
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-panels-ui</artifactId>
    +      <version>${project.version}</version>
    +      <scope>runtime</scope>
    +      <type>xar</type>
    +    </dependency>
    +
    +    <!-- ================================
    +         Test only dependencies
    +         ================================ -->
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-test-docker</artifactId>
    +      <version>${project.version}</version>
    +      <scope>test</scope>
    +    </dependency>
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-panels-test-pageobjects</artifactId>
    +      <version>${project.version}</version>
    +      <scope>test</scope>
    +    </dependency>
    +  </dependencies>
    +  <build>
    +    <testSourceDirectory>src/test/it</testSourceDirectory>
    +    <plugins>
    +      <!-- We need to explicitly include the failsafe plugin since it's not part of the default maven lifecycle -->
    +      <plugin>
    +        <groupId>org.apache.maven.plugins</groupId>
    +        <artifactId>maven-failsafe-plugin</artifactId>
    +      </plugin>
    +    </plugins>
    +  </build>
    +  <profiles>
    +    <profile>
    +      <id>clover</id>
    +      <!-- Add the Clover JAR to the WAR so that it's available at runtime when XWiki executes.
    +           It's needed because instrumented jars in the WAR will call Clover APIs at runtime when they execute. -->
    +      <dependencies>
    +        <dependency>
    +          <groupId>org.openclover</groupId>
    +          <artifactId>clover</artifactId>
    +        </dependency>
    +      </dependencies>
    +      <build>
    +        <plugins>
    +          <plugin>
    +            <groupId>org.apache.maven.plugins</groupId>
    +            <artifactId>maven-failsafe-plugin</artifactId>
    +            <configuration>
    +              <systemProperties combine.children="append">
    +                <!-- Tell the Docker-based test to activate the Clover profile so that the Clover JAR is added to
    +                     WEB-INF/lib -->
    +                <property>
    +                  <name>xwiki.test.ui.profiles</name>
    +                  <value>clover</value>
    +                </property>
    +              </systemProperties>
    +            </configuration>
    +          </plugin>
    +        </plugins>
    +      </build>
    +    </profile>
    +  </profiles>
    +</project>
    \ No newline at end of file
    
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-test/xwiki-platform-help-test-docker/src/test/it/org/xwiki/help/test/ui/docker/AllITs.java+39 0 added
    @@ -0,0 +1,39 @@
    +/*
    + * 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.help.test.ui.docker;
    +
    +import org.junit.jupiter.api.DisplayName;
    +import org.junit.jupiter.api.Nested;
    +import org.xwiki.test.docker.junit5.UITest;
    +
    +/**
    + * All UI Tests for the Help Application.
    + *
    + * @version $Id$
    + */
    +@UITest
    +class AllITs
    +{
    +    @Nested
    +    @DisplayName("Tips panel")
    +    class NestedPanelIT extends TipsPanelIT
    +    {
    +    }
    +}
    
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-test/xwiki-platform-help-test-docker/src/test/it/org/xwiki/help/test/ui/docker/TipsPanelIT.java+116 0 added
    @@ -0,0 +1,116 @@
    +/*
    + * 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.help.test.ui.docker;
    +
    +import org.junit.jupiter.api.BeforeEach;
    +import org.junit.jupiter.api.Order;
    +import org.junit.jupiter.api.Test;
    +import org.xwiki.model.reference.DocumentReference;
    +import org.xwiki.model.reference.LocalDocumentReference;
    +import org.xwiki.panels.test.po.PanelViewPage;
    +import org.xwiki.rendering.syntax.Syntax;
    +import org.xwiki.rendering.wikimacro.internal.WikiMacroClassDocumentInitializer;
    +import org.xwiki.rest.model.jaxb.Objects;
    +import org.xwiki.rest.model.jaxb.Page;
    +import org.xwiki.test.docker.junit5.TestReference;
    +import org.xwiki.test.docker.junit5.UITest;
    +import org.xwiki.test.ui.TestUtils;
    +import org.xwiki.uiextension.internal.UIExtensionClassDocumentInitializer;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.xwiki.test.ui.TestUtils.RestTestUtils.object;
    +import static org.xwiki.test.ui.TestUtils.RestTestUtils.property;
    +
    +/**
    + * Validate the Tips panel.
    + *
    + * @version $Id$
    + */
    +@UITest
    +class TipsPanelIT
    +{
    +    private final static String TIPS_UIXP = "org.xwiki.platform.help.tipsPanel";
    +
    +    private final static String TIPS_UIXP_DISABLED = TIPS_UIXP + ".disabled";
    +
    +    @BeforeEach
    +    void setUp(TestUtils testUtils)
    +    {
    +        testUtils.loginAsSuperAdmin();
    +    }
    +
    +    @Test
    +    @Order(1)
    +    void verifyTipsPropertyIsRestricted(TestUtils testUtils, TestReference testReference) throws Exception
    +    {
    +        // Unregister all tips
    +        switchUIXs(TIPS_UIXP, TIPS_UIXP_DISABLED, testUtils);
    +
    +        // Register a macro to check if the context is restricted
    +        registerIsrestrictedMacro(testUtils);
    +
    +        // Create a tip with tip property
    +        Page tipPage = testUtils.rest().page(testReference);
    +        tipPage.setObjects(new Objects());
    +        org.xwiki.rest.model.jaxb.Object tipObject = object(UIExtensionClassDocumentInitializer.CLASS_REFERENCE_STRING);
    +        tipObject.getProperties().add(property("extensionPointId", "org.xwiki.platform.help.tipsPanel"));
    +        tipObject.getProperties().add(property("parameters",
    +            "tip=execution is restricted: {{isrestricted/}}"));
    +        tipPage.getObjects().getObjectSummaries().add(tipObject);
    +        testUtils.rest().save(tipPage);
    +
    +        // Execute the tip panel and verify the result is restricted (the velocity macro is forbidden)
    +        testUtils.gotoPage(new DocumentReference("xwiki", "Help", "TipsPanel", "WebHome"));
    +        PanelViewPage panelPage = new PanelViewPage();
    +        assertEquals("execution is restricted: true", panelPage.getPanelContent().getText());
    +
    +        // Put back all tips
    +        switchUIXs(TIPS_UIXP_DISABLED, TIPS_UIXP, testUtils);
    +    }
    +
    +    private void switchUIXs(String oldid, String newid, TestUtils testUtils) throws Exception
    +    {
    +        testUtils.executeWiki(String.format(
    +        // @formatter:off
    +            "{{velocity}}\n"
    +            + "#foreach($uix in $services.uix.getExtensions('%s'))\n"
    +            + "  #set ($uixDocument = $xwiki.getDocument($uix.documentReference))\n"
    +            + "  $uixDocument.set('extensionPointId', '%s')\n"
    +            + "  $uixDocument.save()\n"
    +            + "#end\n"
    +            + "{{/velocity}}", oldid, newid)
    +            // @formatter:on
    +            , Syntax.XWIKI_2_1);
    +    }
    +
    +    private void registerIsrestrictedMacro(TestUtils testUtils) throws Exception
    +    {
    +        LocalDocumentReference macroReference = new LocalDocumentReference("Test", "IsrestrictedMacro");
    +        Page macroPage = testUtils.rest().page(macroReference);
    +        macroPage.setObjects(new Objects());
    +        org.xwiki.rest.model.jaxb.Object tipObject = object(WikiMacroClassDocumentInitializer.WIKI_MACRO_CLASS);
    +        tipObject.getProperties().add(property("id", "isrestricted"));
    +        tipObject.getProperties().add(property("supportsInlineMode", 1));
    +        tipObject.getProperties().add(property("code",
    +            "{{velocity}}$wikimacro.context.transformationContext.isRestricted(){{/velocity}}"));
    +        macroPage.getObjects().getObjectSummaries().add(tipObject);
    +        testUtils.rest().save(macroPage);
    +    }
    +}
    
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/Help/TipsPanel/WebHome.xml+3 1 modified
    @@ -173,7 +173,9 @@
     #set ($uixs = $services.uix.getExtensions('org.xwiki.platform.help.tipsPanel'))
     #if ($uixs.size() &gt; 0)
       #set ($index = $mathtool.random(0, $uixs.size()))
    -  $uixs.get($index).getParameters().get('tip')
    +  #set ($tip = $uixs.get($index).getParameters().get('tip'))
    +  ## Execute the content in restricted mode as it's not executed with the right author
    +  {{context restricted="true" transformationContext="transformations" source="script:tip"/}}
     #else
       $services.localization.render('help.tipsPanel.noTipMessage')
     #end
    
  • xwiki-platform-core/xwiki-platform-panels/xwiki-platform-panels-test/xwiki-platform-panels-test-pageobjects/src/main/java/org/xwiki/panels/test/po/PanelViewPage.java+14 0 modified
    @@ -19,6 +19,8 @@
      */
     package org.xwiki.panels.test.po;
     
    +import org.openqa.selenium.WebElement;
    +import org.openqa.selenium.support.FindBy;
     import org.xwiki.test.ui.po.ViewPage;
     
     /**
    @@ -29,10 +31,22 @@
      */
     public class PanelViewPage extends ViewPage
     {
    +    @FindBy(className = "xwikipanelcontents")
    +    private WebElement content;
    +
         @SuppressWarnings("unchecked")
         @Override
         protected PanelEditPage createInlinePage()
         {
             return new PanelEditPage();
         }
    +
    +    /**
    +     * @since 15.1RC1
    +     * @since 14.10.5
    +     */
    +    public WebElement getPanelContent()
    +    {
    +        return this.content;
    +    }
     }
    
  • xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/TestUtils.java+21 9 modified
    @@ -40,6 +40,7 @@
     import java.util.Objects;
     import java.util.Properties;
     import java.util.Set;
    +import java.util.UUID;
     import java.util.regex.Matcher;
     import java.util.regex.Pattern;
     
    @@ -86,6 +87,7 @@
     import org.xwiki.model.reference.ObjectPropertyReference;
     import org.xwiki.model.reference.ObjectReference;
     import org.xwiki.model.reference.SpaceReference;
    +import org.xwiki.rendering.syntax.Syntax;
     import org.xwiki.rest.model.jaxb.Page;
     import org.xwiki.rest.model.jaxb.Property;
     import org.xwiki.rest.model.jaxb.Xwiki;
    @@ -1124,15 +1126,23 @@ public String getURL(EntityReference reference, String action, String queryStrin
          */
         public String executeAndGetBodyAsString(EntityReference reference, Map<String, ?> queryParameters) throws Exception
         {
    -        String url = getURL(reference, "get", toQueryString(queryParameters));
    -
    -        GetMethod getMethod = executeGet(url);
    +        gotoPage(getURL(reference, "get", toQueryString(queryParameters)));
    +        
    +        return getDriver().getPageSource();
    +    }
     
    -        String result = getMethod.getResponseBodyAsString();
    +    /**
    +     * @since 15.1RC1
    +     * @since 14.10.5
    +     */
    +    public String executeWiki(String wikiContent, Syntax wikiSyntax) throws Exception
    +    {
    +        LocalDocumentReference reference =
    +            new LocalDocumentReference(List.of("Test", "Execute"), UUID.randomUUID().toString());
     
    -        getMethod.releaseConnection();
    +        rest().savePage(reference, wikiContent, wikiSyntax.toIdString(), null, null);
     
    -        return result;
    +        return executeAndGetBodyAsString(reference, null);
         }
     
         /**
    @@ -1595,9 +1605,11 @@ public String toQueryString(Map<String, ?> queryParameters)
         {
             StringBuilder builder = new StringBuilder();
     
    -        for (Map.Entry<String, ?> entry : queryParameters.entrySet()) {
    -            addQueryStringEntry(builder, entry.getKey(), entry.getValue());
    -            builder.append('&');
    +        if (queryParameters != null) {
    +            for (Map.Entry<String, ?> entry : queryParameters.entrySet()) {
    +                addQueryStringEntry(builder, entry.getKey(), entry.getValue());
    +                builder.append('&');
    +            }
             }
     
             return builder.toString();
    

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

News mentions

0

No linked articles in our index yet.