VYPR
Critical severityNVD Advisory· Published Apr 18, 2023· Updated Feb 5, 2025

Code injection in display method used in user profiles in xwiki-platform

CVE-2023-29523

Description

XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. Any user who can edit their own user profile can execute arbitrary script macros including Groovy and Python macros that allow remote code execution including unrestricted read and write access to all wiki contents. The same vulnerability can also be exploited in other contexts where the display method on a document is used to display a field with wiki syntax, for example in applications created using App Within Minutes. This has been patched in XWiki 13.10.11, 14.4.8, 14.10.2 and 15.0RC1. There is no workaround apart from upgrading.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-oldcoreMaven
>= 3.3-milestone-1, < 13.10.1113.10.11
org.xwiki.platform:xwiki-platform-oldcoreMaven
>= 14.0-rc-1, < 14.4.814.4.8
org.xwiki.platform:xwiki-platform-oldcoreMaven
>= 14.5, < 14.10.214.10.2

Affected products

1

Patches

1
0d547181389f

XWIKI-20327: Escape closing HTML macro in XWikiDocument#display

https://github.com/xwiki/xwiki-platformMichael HamannDec 1, 2022via ghsa
2 files changed · +41 3
  • xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java+14 3 modified
    @@ -220,6 +220,8 @@ public class XWikiDocument implements DocumentModelBridge, Cloneable
     
         private static final String TM_FAILEDDOCUMENTPARSE = "core.document.error.failedParse";
     
    +    private static final String CLOSE_HTML_MACRO = "{{/html}}";
    +
         /**
          * An attachment waiting to be deleted at next document save.
          *
    @@ -3885,10 +3887,19 @@ public String display(String fieldname, String type, String pref, BaseObject obj
                 // We test if we're inside the rendering engine since it's also possible that this display() method is
                 // called directly from a template and in this case we only want HTML as a result and not wiki syntax.
                 // TODO: find a more generic way to handle html macro because this works only for XWiki 1.0 and XWiki 2.0
    -            // Add the {{html}}{{/html}} only when result really contains html since it's not needed for pure text
    -            if (isInRenderingEngine && !is10Syntax(wrappingSyntaxId) && HTMLUtils.containsElementText(result)) {
    +            // Add the {{html}}{{/html}} only when result really contains html or { which could be part of an XWiki
    +            // macro syntax since it's not needed for pure text
    +            if (isInRenderingEngine && !is10Syntax(wrappingSyntaxId)
    +                && (HTMLUtils.containsElementText(result) || result.indexOf("{") != -1))
    +            {
                     result.insert(0, "{{html clean=\"false\" wiki=\"false\"}}");
    -                result.append("{{/html}}");
    +                // Escape closing HTML macro syntax.
    +                int startIndex = 0;
    +                // Start searching at the last match to avoid scanning the whole string again.
    +                while ((startIndex = result.indexOf(CLOSE_HTML_MACRO, startIndex)) != -1) {
    +                    result.replace(startIndex, startIndex + 2, "&#123;&#123;");
    +                }
    +                result.append(CLOSE_HTML_MACRO);
                 }
     
                 return result.toString();
    
  • xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/doc/XWikiDocumentTest.java+27 0 modified
    @@ -59,6 +59,7 @@
     import com.xpn.xwiki.api.DocumentSection;
     import com.xpn.xwiki.objects.BaseObject;
     import com.xpn.xwiki.objects.classes.BaseClass;
    +import com.xpn.xwiki.objects.classes.PropertyClass;
     import com.xpn.xwiki.objects.classes.TextAreaClass;
     import com.xpn.xwiki.store.XWikiStoreInterface;
     import com.xpn.xwiki.store.XWikiVersioningStoreInterface;
    @@ -76,10 +77,12 @@
     import static org.junit.jupiter.api.Assertions.assertSame;
     import static org.junit.jupiter.api.Assertions.assertTrue;
     import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.ArgumentMatchers.anyBoolean;
     import static org.mockito.ArgumentMatchers.anyInt;
     import static org.mockito.ArgumentMatchers.anyString;
     import static org.mockito.ArgumentMatchers.argThat;
     import static org.mockito.ArgumentMatchers.eq;
    +import static org.mockito.Mockito.doAnswer;
     import static org.mockito.Mockito.doReturn;
     import static org.mockito.Mockito.mock;
     import static org.mockito.Mockito.verify;
    @@ -647,6 +650,30 @@ public void displayTemplate20()
             assertEquals("<p>area</p>", this.document.display("area", "view", this.oldcore.getXWikiContext()));
         }
     
    +    @Test
    +    void displayEscapesClosingHTMLMacro()
    +    {
    +        this.oldcore.getXWikiContext().put("isInRenderingEngine", true);
    +        when(this.xWiki.getCurrentContentSyntaxId(any())).thenReturn("xwiki/2.1");
    +        this.document.setSyntax(Syntax.XWIKI_2_0);
    +
    +        BaseObject object = mock(BaseObject.class);
    +        when(object.getOwnerDocument()).thenReturn(this.document);
    +
    +        BaseClass xClass = mock(BaseClass.class);
    +        when(object.getXClass(any())).thenReturn(xClass);
    +        PropertyClass propertyInterface = mock(PropertyClass.class);
    +        when(xClass.get("mock")).thenReturn(propertyInterface);
    +        doAnswer(call -> {
    +            call.getArgument(0, StringBuffer.class).append("{{/html}}content{{/html}}");
    +            return null;
    +        }).when(propertyInterface).displayView(any(StringBuffer.class), eq("mock"), any(String.class), eq(object),
    +            anyBoolean(), any(XWikiContext.class));
    +
    +        assertEquals("{{html clean=\"false\" wiki=\"false\"}}&#123;&#123;/html}}content&#123;&#123;/html}}{{/html}}",
    +            this.document.display("mock", "view", object, this.oldcore.getXWikiContext()));
    +    }
    +
         @Test
         public void convertSyntax() throws XWikiException
         {
    

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

6

News mentions

0

No linked articles in our index yet.