VYPR
Critical severityNVD Advisory· Published Apr 10, 2024· Updated Aug 13, 2024

XWiki Platform: Remote code execution from account via SearchSuggestSourceSheet

CVE-2024-31465

Description

XWiki Platform is a generic wiki platform. Starting in version 5.0-rc-1 and prior to versions 14.10.20, 15.5.4, and 15.9-rc-1, any user with edit right on any page can execute any code on the server by adding an object of type XWiki.SearchSuggestSourceClass to their user profile or any other page. This compromises the confidentiality, integrity and availability of the whole XWiki installation. This vulnerability has been patched in XWiki 14.10.20, 15.5.4 and 15.10 RC1. As a workaround, manually apply the patch to the document XWiki.SearchSuggestSourceSheet.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-search-uiMaven
>= 5.2-milestone-2, < 14.10.2014.10.20
org.xwiki.platform:xwiki-platform-search-uiMaven
>= 15.0-rc-1, < 15.5.415.5.4
org.xwiki.platform:xwiki-platform-search-uiMaven
>= 15.6-rc-1, < 15.10-rc-115.10-rc-1

Affected products

1

Patches

3
0317a3aa7806

XWIKI-21474: Improve escaping in XWiki.SearchSuggestSourceSheet

https://github.com/xwiki/xwiki-platformpjeanjeanNov 9, 2023via ghsa
2 files changed · +91 1
  • xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-ui/src/main/resources/XWiki/SearchSuggestSourceSheet.xml+1 1 modified
    @@ -70,7 +70,7 @@
         : #if ($editing)
             $doc.display($property.name, 'edit')
           #else
    -        {{{$!object.getProperty($property.name).value}}}
    +        $services.rendering.escape($!object.getProperty($property.name).value, 'xwiki/2.1')
           #end
       #end
     #end
    
  • xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-ui/src/test/java/org/xwiki/search/ui/SearchSuggestSourceSheetPageTest.java+90 0 added
    @@ -0,0 +1,90 @@
    +package org.xwiki.search.ui;
    +
    +import org.jsoup.nodes.Document;
    +import org.jsoup.select.Elements;
    +import org.junit.jupiter.api.BeforeEach;
    +import org.junit.jupiter.api.Test;
    +import org.xwiki.model.reference.DocumentReference;
    +import org.xwiki.rendering.RenderingScriptServiceComponentList;
    +import org.xwiki.rendering.internal.configuration.DefaultRenderingConfigurationComponentList;
    +import org.xwiki.test.annotation.ComponentList;
    +import org.xwiki.test.page.HTML50ComponentList;
    +import org.xwiki.test.page.PageTest;
    +import org.xwiki.test.page.TestNoScriptMacro;
    +import org.xwiki.test.page.XWikiSyntax21ComponentList;
    +import org.xwiki.uiextension.script.UIExtensionScriptServiceComponentList;
    +
    +import com.xpn.xwiki.doc.XWikiDocument;
    +import com.xpn.xwiki.objects.BaseObject;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +
    +/**
    + * Page test for {@code XWiki.SearchSuggestSourceSheet}.
    + *
    + * @version $Id$
    + */
    +@ComponentList({
    +    TestNoScriptMacro.class
    +})
    +@UIExtensionScriptServiceComponentList
    +@RenderingScriptServiceComponentList
    +@DefaultRenderingConfigurationComponentList
    +@HTML50ComponentList
    +@XWikiSyntax21ComponentList
    +class SearchSuggestSourceSheetPageTest extends PageTest
    +{
    +    private static final String WIKI_NAME = "xwiki";
    +
    +    private static final String XWIKI_SPACE = "XWiki";
    +
    +    private static final DocumentReference SEARCH_SUGGEST_SOURCE_SHEET =
    +        new DocumentReference(WIKI_NAME, XWIKI_SPACE, "SearchSuggestSourceSheet");
    +
    +    private static final DocumentReference SEARCH_SUGGEST_SOURCE_CLASS =
    +        new DocumentReference(WIKI_NAME, XWIKI_SPACE, "SearchSuggestSourceClass");
    +
    +    private XWikiDocument searchSuggestSourceSheetDocument;
    +
    +    @BeforeEach
    +    void setUp() throws Exception
    +    {
    +        this.xwiki.initializeMandatoryDocuments(this.context);
    +
    +        this.loadPage(SEARCH_SUGGEST_SOURCE_CLASS);
    +        this.searchSuggestSourceSheetDocument = this.loadPage(SEARCH_SUGGEST_SOURCE_SHEET);
    +    }
    +
    +    @Test
    +    void checkPropertiesEscaping() throws Exception
    +    {
    +        // Create an instance of XWiki.SearchSuggestSourceClass with properties that require escaping.
    +        String[] properties = new String[]{"name", "engine", "url", "query", "resultsNumber", "icon"};
    +        String unescapedProperty = "{{/html}}}}}{{noscript}}";
    +        BaseObject searchSuggestSource =
    +            this.searchSuggestSourceSheetDocument.newXObject(SEARCH_SUGGEST_SOURCE_CLASS, this.context);
    +        for (String property : properties) {
    +            searchSuggestSource.set(property, unescapedProperty, this.context);
    +        }
    +        this.xwiki.saveDocument(this.searchSuggestSourceSheetDocument, this.context);
    +
    +        this.context.setDoc(this.searchSuggestSourceSheetDocument);
    +        Document document = renderHTMLPage(this.searchSuggestSourceSheetDocument);
    +        Elements labels = document.getElementsByTag("label");
    +        Elements values = document.getElementsByTag("dd");
    +
    +        // Check that the value of the property has not been evaluated for each label that we know of.
    +        for (String property : properties) {
    +            int iLabel = -1;
    +            for (int i = 0; i < labels.size(); i++) {
    +                if (labels.get(i).text().replaceAll("^.*_", "").equals(property)) {
    +                    iLabel = i;
    +                    break;
    +                }
    +            }
    +            assertTrue(iLabel >= 0, "Could not find property " + property + " in rendered document.");
    +            assertEquals(unescapedProperty, values.get(iLabel).text());
    +        }
    +    }
    +}
    
2740974c32db

XWIKI-21474: Improve escaping in XWiki.SearchSuggestSourceSheet

https://github.com/xwiki/xwiki-platformpjeanjeanNov 9, 2023via ghsa
2 files changed · +91 1
  • xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-ui/src/main/resources/XWiki/SearchSuggestSourceSheet.xml+1 1 modified
    @@ -70,7 +70,7 @@
         : #if ($editing)
             $doc.display($property.name, 'edit')
           #else
    -        {{{$!object.getProperty($property.name).value}}}
    +        $services.rendering.escape($!object.getProperty($property.name).value, 'xwiki/2.1')
           #end
       #end
     #end
    
  • xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-ui/src/test/java/org/xwiki/search/ui/SearchSuggestSourceSheetPageTest.java+90 0 added
    @@ -0,0 +1,90 @@
    +package org.xwiki.search.ui;
    +
    +import org.jsoup.nodes.Document;
    +import org.jsoup.select.Elements;
    +import org.junit.jupiter.api.BeforeEach;
    +import org.junit.jupiter.api.Test;
    +import org.xwiki.model.reference.DocumentReference;
    +import org.xwiki.rendering.RenderingScriptServiceComponentList;
    +import org.xwiki.rendering.internal.configuration.DefaultRenderingConfigurationComponentList;
    +import org.xwiki.test.annotation.ComponentList;
    +import org.xwiki.test.page.HTML50ComponentList;
    +import org.xwiki.test.page.PageTest;
    +import org.xwiki.test.page.TestNoScriptMacro;
    +import org.xwiki.test.page.XWikiSyntax21ComponentList;
    +import org.xwiki.uiextension.script.UIExtensionScriptServiceComponentList;
    +
    +import com.xpn.xwiki.doc.XWikiDocument;
    +import com.xpn.xwiki.objects.BaseObject;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +
    +/**
    + * Page test for {@code XWiki.SearchSuggestSourceSheet}.
    + *
    + * @version $Id$
    + */
    +@ComponentList({
    +    TestNoScriptMacro.class
    +})
    +@UIExtensionScriptServiceComponentList
    +@RenderingScriptServiceComponentList
    +@DefaultRenderingConfigurationComponentList
    +@HTML50ComponentList
    +@XWikiSyntax21ComponentList
    +class SearchSuggestSourceSheetPageTest extends PageTest
    +{
    +    private static final String WIKI_NAME = "xwiki";
    +
    +    private static final String XWIKI_SPACE = "XWiki";
    +
    +    private static final DocumentReference SEARCH_SUGGEST_SOURCE_SHEET =
    +        new DocumentReference(WIKI_NAME, XWIKI_SPACE, "SearchSuggestSourceSheet");
    +
    +    private static final DocumentReference SEARCH_SUGGEST_SOURCE_CLASS =
    +        new DocumentReference(WIKI_NAME, XWIKI_SPACE, "SearchSuggestSourceClass");
    +
    +    private XWikiDocument searchSuggestSourceSheetDocument;
    +
    +    @BeforeEach
    +    void setUp() throws Exception
    +    {
    +        this.xwiki.initializeMandatoryDocuments(this.context);
    +
    +        this.loadPage(SEARCH_SUGGEST_SOURCE_CLASS);
    +        this.searchSuggestSourceSheetDocument = this.loadPage(SEARCH_SUGGEST_SOURCE_SHEET);
    +    }
    +
    +    @Test
    +    void checkPropertiesEscaping() throws Exception
    +    {
    +        // Create an instance of XWiki.SearchSuggestSourceClass with properties that require escaping.
    +        String[] properties = new String[]{"name", "engine", "url", "query", "resultsNumber", "icon"};
    +        String unescapedProperty = "{{/html}}}}}{{noscript}}";
    +        BaseObject searchSuggestSource =
    +            this.searchSuggestSourceSheetDocument.newXObject(SEARCH_SUGGEST_SOURCE_CLASS, this.context);
    +        for (String property : properties) {
    +            searchSuggestSource.set(property, unescapedProperty, this.context);
    +        }
    +        this.xwiki.saveDocument(this.searchSuggestSourceSheetDocument, this.context);
    +
    +        this.context.setDoc(this.searchSuggestSourceSheetDocument);
    +        Document document = renderHTMLPage(this.searchSuggestSourceSheetDocument);
    +        Elements labels = document.getElementsByTag("label");
    +        Elements values = document.getElementsByTag("dd");
    +
    +        // Check that the value of the property has not been evaluated for each label that we know of.
    +        for (String property : properties) {
    +            int iLabel = -1;
    +            for (int i = 0; i < labels.size(); i++) {
    +                if (labels.get(i).text().replaceAll("^.*_", "").equals(property)) {
    +                    iLabel = i;
    +                    break;
    +                }
    +            }
    +            assertTrue(iLabel >= 0, "Could not find property " + property + " in rendered document.");
    +            assertEquals(unescapedProperty, values.get(iLabel).text());
    +        }
    +    }
    +}
    
6a7f19f64240

XWIKI-21474: Improve escaping in XWiki.SearchSuggestSourceSheet

https://github.com/xwiki/xwiki-platformpjeanjeanNov 9, 2023via ghsa
2 files changed · +91 1
  • xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-ui/src/main/resources/XWiki/SearchSuggestSourceSheet.xml+1 1 modified
    @@ -70,7 +70,7 @@
         : #if ($editing)
             $doc.display($property.name, 'edit')
           #else
    -        {{{$!object.getProperty($property.name).value}}}
    +        $services.rendering.escape($!object.getProperty($property.name).value, 'xwiki/2.1')
           #end
       #end
     #end
    
  • xwiki-platform-core/xwiki-platform-search/xwiki-platform-search-ui/src/test/java/org/xwiki/search/ui/SearchSuggestSourceSheetPageTest.java+90 0 added
    @@ -0,0 +1,90 @@
    +package org.xwiki.search.ui;
    +
    +import org.jsoup.nodes.Document;
    +import org.jsoup.select.Elements;
    +import org.junit.jupiter.api.BeforeEach;
    +import org.junit.jupiter.api.Test;
    +import org.xwiki.model.reference.DocumentReference;
    +import org.xwiki.rendering.RenderingScriptServiceComponentList;
    +import org.xwiki.rendering.internal.configuration.DefaultRenderingConfigurationComponentList;
    +import org.xwiki.test.annotation.ComponentList;
    +import org.xwiki.test.page.HTML50ComponentList;
    +import org.xwiki.test.page.PageTest;
    +import org.xwiki.test.page.TestNoScriptMacro;
    +import org.xwiki.test.page.XWikiSyntax21ComponentList;
    +import org.xwiki.uiextension.script.UIExtensionScriptServiceComponentList;
    +
    +import com.xpn.xwiki.doc.XWikiDocument;
    +import com.xpn.xwiki.objects.BaseObject;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +
    +/**
    + * Page test for {@code XWiki.SearchSuggestSourceSheet}.
    + *
    + * @version $Id$
    + */
    +@ComponentList({
    +    TestNoScriptMacro.class
    +})
    +@UIExtensionScriptServiceComponentList
    +@RenderingScriptServiceComponentList
    +@DefaultRenderingConfigurationComponentList
    +@HTML50ComponentList
    +@XWikiSyntax21ComponentList
    +class SearchSuggestSourceSheetPageTest extends PageTest
    +{
    +    private static final String WIKI_NAME = "xwiki";
    +
    +    private static final String XWIKI_SPACE = "XWiki";
    +
    +    private static final DocumentReference SEARCH_SUGGEST_SOURCE_SHEET =
    +        new DocumentReference(WIKI_NAME, XWIKI_SPACE, "SearchSuggestSourceSheet");
    +
    +    private static final DocumentReference SEARCH_SUGGEST_SOURCE_CLASS =
    +        new DocumentReference(WIKI_NAME, XWIKI_SPACE, "SearchSuggestSourceClass");
    +
    +    private XWikiDocument searchSuggestSourceSheetDocument;
    +
    +    @BeforeEach
    +    void setUp() throws Exception
    +    {
    +        this.xwiki.initializeMandatoryDocuments(this.context);
    +
    +        this.loadPage(SEARCH_SUGGEST_SOURCE_CLASS);
    +        this.searchSuggestSourceSheetDocument = this.loadPage(SEARCH_SUGGEST_SOURCE_SHEET);
    +    }
    +
    +    @Test
    +    void checkPropertiesEscaping() throws Exception
    +    {
    +        // Create an instance of XWiki.SearchSuggestSourceClass with properties that require escaping.
    +        String[] properties = new String[]{"name", "engine", "url", "query", "resultsNumber", "icon"};
    +        String unescapedProperty = "{{/html}}}}}{{noscript}}";
    +        BaseObject searchSuggestSource =
    +            this.searchSuggestSourceSheetDocument.newXObject(SEARCH_SUGGEST_SOURCE_CLASS, this.context);
    +        for (String property : properties) {
    +            searchSuggestSource.set(property, unescapedProperty, this.context);
    +        }
    +        this.xwiki.saveDocument(this.searchSuggestSourceSheetDocument, this.context);
    +
    +        this.context.setDoc(this.searchSuggestSourceSheetDocument);
    +        Document document = renderHTMLPage(this.searchSuggestSourceSheetDocument);
    +        Elements labels = document.getElementsByTag("label");
    +        Elements values = document.getElementsByTag("dd");
    +
    +        // Check that the value of the property has not been evaluated for each label that we know of.
    +        for (String property : properties) {
    +            int iLabel = -1;
    +            for (int i = 0; i < labels.size(); i++) {
    +                if (labels.get(i).text().replaceAll("^.*_", "").equals(property)) {
    +                    iLabel = i;
    +                    break;
    +                }
    +            }
    +            assertTrue(iLabel >= 0, "Could not find property " + property + " in rendered document.");
    +            assertEquals(unescapedProperty, values.get(iLabel).text());
    +        }
    +    }
    +}
    

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

8

News mentions

0

No linked articles in our index yet.