VYPR
Critical severityNVD Advisory· Published Dec 12, 2024· Updated Dec 13, 2024

XWiki allows remote code execution from account through macro descriptions and XWiki.XWikiSyntaxMacrosList

CVE-2024-55877

Description

XWiki Platform is a generic wiki platform. Starting in version 9.7-rc-1 and prior to versions 15.10.11, 16.4.1, and 16.5.0, any user with an account can perform arbitrary remote code execution by adding instances of XWiki.WikiMacroClass to any page. This compromises the confidentiality, integrity and availability of the whole XWiki installation. This vulnerability has been fixed in XWiki 15.10.11, 16.4.1 and 16.5.0. It is possible to manually apply the patch to the page XWiki.XWikiSyntaxMacrosList as a workaround.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-help-uiMaven
>= 9.7-rc-1, < 15.10.1115.10.11
org.xwiki.platform:xwiki-platform-help-uiMaven
>= 16.0.0-rc-1, < 16.4.116.4.1
org.xwiki.platform:xwiki-platform-help-uiMaven
>= 16.5.0-rc-1, < 16.5.016.5.0

Affected products

1

Patches

1
40e1afe001d6

XWIKI-22030: Improve escaping in macros list

https://github.com/xwiki/xwiki-platformPierre JeanjeanMay 7, 2024via ghsa
2 files changed · +56 18
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/XWiki/XWikiSyntaxMacrosList.xml+2 2 modified
    @@ -39,10 +39,10 @@
       <content>{{velocity}}
     ## If the translation key exists, use its value, otherwise use to the provided fallback value. 
     #macro (translateOrElse $translationKey $fallback)
    - #if($services.localization.get($translationKey))
    +  #if($services.localization.get($translationKey))
         $services.rendering.escape($services.localization.render($translationKey), 'xwiki/2.1')##
       #else
    -    $fallback##
    +    $services.rendering.escape($fallback, 'xwiki/2.1')##
       #end
     #end
     
    
  • xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/test/java/org/xwiki/help/XWikiSyntaxMacrosListPageTest.java+54 16 modified
    @@ -27,6 +27,7 @@
     import org.jsoup.nodes.Document;
     import org.jsoup.nodes.Element;
     import org.jsoup.select.Elements;
    +import org.junit.jupiter.api.BeforeEach;
     import org.junit.jupiter.api.Test;
     import org.xwiki.context.internal.concurrent.DefaultContextStoreManager;
     import org.xwiki.localization.macro.internal.TranslationMacro;
    @@ -49,13 +50,15 @@
     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 com.xpn.xwiki.DefaultSkinAccessBridge;
     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.assertNotNull;
     import static org.mockito.ArgumentMatchers.any;
     import static org.mockito.Mockito.mock;
     import static org.mockito.Mockito.when;
    @@ -88,19 +91,30 @@
         // End of XWikiWikiModel
         DocumentXHTMLLinkTypeRenderer.class,
         DocumentResourceReferenceEntityReferenceResolver.class,
    +    TestNoScriptMacro.class,
         TranslationMacro.class
     })
     class XWikiSyntaxMacrosListPageTest extends PageTest
     {
         public static final DocumentReference DOCUMENT_REFERENCE =
             new DocumentReference("xwiki", "XWiki", "XWikiSyntaxMacrosList");
     
    -    @Test
    -    void renderTable() throws Exception
    +    private DefaultWikiMacro myMacro;
    +
    +    @BeforeEach
    +    void setUp() throws Exception
         {
             // Initialize "WikiMacroClass"
             this.xwiki.initializeMandatoryDocuments(this.context);
     
    +        // Mock the database.
    +        Query query = mock(Query.class);
    +        QueryManagerScriptService queryManagerScriptService =
    +            this.componentManager.registerMockComponent(ScriptService.class, "query", QueryManagerScriptService.class,
    +                false);
    +        when(queryManagerScriptService.xwql(any())).thenReturn(query);
    +        when(query.execute()).thenReturn(List.of("xwiki:XWiki.MyMacro"));
    +
             // Create a wiki macro.
             XWikiDocument myMacroDocument = this.xwiki.getDocument(new DocumentReference("xwiki", "XWiki", "MyMacro"),
                 this.context);
    @@ -111,20 +125,17 @@ void renderTable() throws Exception
             this.xwiki.saveDocument(myMacroDocument, this.context);
     
             // Register the wiki macro component.
    -        DefaultWikiMacro myMacro =
    +        this.myMacro =
                 this.componentManager.registerMockComponent(Macro.class, "mymacro", DefaultWikiMacro.class, false);
    -        DefaultMacroDescriptor macroDescriptor =
    -            new DefaultMacroDescriptor(new MacroId("mymacro"), "My Macro", "My Macro Description");
    -        macroDescriptor.setDefaultCategories(Set.of("Category1", "Category2"));
    -        when(myMacro.getDescriptor()).thenReturn(macroDescriptor);
    +    }
     
    -        // Mock the database.
    -        Query query = mock(Query.class);
    -        QueryManagerScriptService queryManagerScriptService =
    -            this.componentManager.registerMockComponent(ScriptService.class, "query", QueryManagerScriptService.class,
    -                false);
    -        when(queryManagerScriptService.xwql(any())).thenReturn(query);
    -        when(query.execute()).thenReturn(List.of("xwiki:XWiki.MyMacro"));
    +    @Test
    +    void renderTable() throws Exception
    +    {
    +        DefaultMacroDescriptor macroDescriptor = new DefaultMacroDescriptor(new MacroId("mymacro"), "My Macro",
    +            "My Macro Description");
    +        macroDescriptor.setDefaultCategories(Set.of("Category1", "Category2"));
    +        when(this.myMacro.getDescriptor()).thenReturn(macroDescriptor);
     
             // Render the page.
             Document document = renderHTMLPage(DOCUMENT_REFERENCE);
    @@ -144,12 +155,39 @@ void renderTable() throws Exception
                 "XWiki.WikiMacroClass_visibility_Global");
             assertWikiMacro(trs.get(3), "mymacro", "/xwiki/bin/view/XWiki/MyMacro", "My Macro",
                 Set.of("Category1", "Category2"), "My Macro Description", "XWiki.WikiMacroClass_visibility_WIKI");
    -        assertJavaMacro(trs.get(4), "translation", "Translation", "Content",
    +        assertJavaMacro(trs.get(4), "noscript", "NoScript", "", "No Script!", "XWiki.WikiMacroClass_visibility_Global");
    +        assertJavaMacro(trs.get(5), "translation", "Translation", "Content",
                 "Display a translation message.", "XWiki.WikiMacroClass_visibility_Global");
    -        assertJavaMacro(trs.get(5), "velocity", "Velocity", "Development", "Executes a Velocity script.",
    +        assertJavaMacro(trs.get(6), "velocity", "Velocity", "Development", "Executes a Velocity script.",
                 "XWiki.WikiMacroClass_visibility_Global");
         }
     
    +    @Test
    +    void checkTableEscaping() throws Exception
    +    {
    +        String unescapedString = "{{noscript /}}";
    +
    +        DefaultMacroDescriptor macroDescriptor = new DefaultMacroDescriptor(new MacroId("mymacro"), unescapedString,
    +            unescapedString);
    +        macroDescriptor.setDefaultCategories(Set.of(unescapedString));
    +        when(this.myMacro.getDescriptor()).thenReturn(macroDescriptor);
    +
    +        Document document = renderHTMLPage(DOCUMENT_REFERENCE);
    +
    +        Elements trs = document.select("tr");
    +        Element myMacroTr = null;
    +        for (Element tr : trs) {
    +            Element th = tr.selectFirst("td");
    +            if (th != null && th.text().equals("mymacro")) {
    +                myMacroTr = tr;
    +            }
    +        }
    +
    +        assertNotNull(myMacroTr);
    +        assertWikiMacro(myMacroTr, "mymacro", "/xwiki/bin/view/XWiki/MyMacro", unescapedString, Set.of(unescapedString),
    +            unescapedString, "XWiki.WikiMacroClass_visibility_WIKI");
    +    }
    +
         private void assertWikiMacro(Element rowElement, String id, String link, String name, Set<String> categories,
             String description, String visibility)
         {
    

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.