VYPR
High severityNVD Advisory· Published Jun 13, 2025· Updated Jun 13, 2025

XWiki allows remote code execution through default value of wiki macro wiki-type parameters

CVE-2025-49581

Description

XWiki is a generic wiki platform. Any user with edit right on a page (could be the user's profile) can execute code (Groovy, Python, Velocity) with programming right by defining a wiki macro. This allows full access to the whole XWiki installation. The main problem is that if a wiki macro parameter allows wiki syntax, its default value is executed with the rights of the author of the document where it is used. This can be exploited by overriding a macro like the children macro that is used in a page that has programming right like the page XWiki.ChildrenMacro and thus allows arbitrary script macros. This vulnerability has been patched in XWiki 16.4.7, 16.10.3 and 17.0.0 by executing wiki parameters with the rights of the wiki macro's author when the parameter's value is the default value.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.xwiki.platform:xwiki-platform-rendering-wikimacro-storeMaven
>= 11.10.11
org.xwiki.platform:xwiki-platform-rendering-wikimacro-storeMaven
>= 12.6.3
org.xwiki.platform:xwiki-platform-rendering-wikimacro-storeMaven
>= 12.8-rc-1, < 16.4.716.4.7
org.xwiki.platform:xwiki-platform-rendering-wikimacro-storeMaven
>= 16.5.0-rc-1, < 16.10.316.10.3
org.xwiki.platform:xwiki-platform-rendering-wikimacro-storeMaven
>= 17.0.0-rc-1, < 17.0.017.0.0

Affected products

1

Patches

1
c99d501ed41c

XWIKI-22760: Execute wiki macro parameter's default values in the macro's context

https://github.com/xwiki/xwiki-platformMichael HamannJan 15, 2025via ghsa
7 files changed · +239 5
  • xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-wikimacro/xwiki-platform-rendering-wikimacro-store/pom.xml+5 0 modified
    @@ -67,6 +67,11 @@
           <artifactId>xwiki-platform-rendering-async-default</artifactId>
           <version>${project.version}</version>
         </dependency>
    +    <dependency>
    +      <groupId>org.xwiki.platform</groupId>
    +      <artifactId>xwiki-platform-security-requiredrights-default</artifactId>
    +      <version>${project.version}</version>
    +    </dependency>
     
         <!-- Test dependencies -->
         <dependency>
    
  • xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-wikimacro/xwiki-platform-rendering-wikimacro-store/src/main/java/org/xwiki/rendering/wikimacro/internal/DefaultWikiMacroRenderer.java+12 4 modified
    @@ -27,6 +27,7 @@
     import java.util.LinkedList;
     import java.util.List;
     import java.util.Map;
    +import java.util.Objects;
     import java.util.regex.Matcher;
     import java.util.regex.Pattern;
     
    @@ -731,10 +732,11 @@ private Block resolveMacroContent(MacroMarkerBlock macroBlock)
             return macroBlock;
         }
     
    -    private XDOM parseWiki(String macroContent, boolean inline) throws RenderingException
    +    private XDOM parseWiki(String macroContent, Syntax syntax, boolean transform, boolean inline)
    +        throws RenderingException
         {
             try {
    -            return this.contentParser.parse(macroContent, this.syncContext, false, inline);
    +            return this.contentParser.parse(macroContent, syntax, this.syncContext, transform, null, inline);
             } catch (MacroExecutionException e) {
                 throw new RenderingException("Failed to parse the passed content", e);
             }
    @@ -750,7 +752,7 @@ private XDOM parseContent(String macroContent, boolean inline) throws RenderingE
                     throw new RenderingException("Error while parsing the macro content in plain text.", e);
                 }
             } else {
    -            return parseWiki(macroContent, inline);
    +            return parseWiki(macroContent, null, false, inline);
             }
         }
     
    @@ -795,7 +797,13 @@ private XDOM parseParameterValue(String macroParameterContent, String macroParam
                     throw new MacroExecutionException("Error while parsing the macro parameter content in plain.", e);
                 }
             } else {
    -            return parseWiki(macroParameterContent, inline);
    +            boolean executeWithMacroAuthor =
    +                Objects.equals(macroParameterContent, parameterDescriptor.getDefaultValue());
    +            if (executeWithMacroAuthor) {
    +                return parseWiki(macroParameterContent, this.wikimacro.getSourceSyntax(), true, inline);
    +            } else {
    +                return parseWiki(macroParameterContent, null, false, inline);
    +            }
             }
         }
     
    
  • xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-wikimacro/xwiki-platform-rendering-wikimacro-store/src/main/java/org/xwiki/rendering/wikimacro/internal/WikiMacroParameterObjectRequiredRightAnalyzer.java+84 0 added
    @@ -0,0 +1,84 @@
    +/*
    + * 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.rendering.wikimacro.internal;
    +
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import javax.inject.Inject;
    +import javax.inject.Named;
    +import javax.inject.Singleton;
    +
    +import org.apache.commons.lang3.StringUtils;
    +import org.xwiki.component.annotation.Component;
    +import org.xwiki.component.util.ReflectionUtils;
    +import org.xwiki.platform.security.requiredrights.RequiredRightAnalysisResult;
    +import org.xwiki.platform.security.requiredrights.RequiredRightAnalyzer;
    +import org.xwiki.platform.security.requiredrights.RequiredRightsException;
    +import org.xwiki.platform.security.requiredrights.internal.analyzer.ObjectPropertyRequiredRightAnalyzer;
    +import org.xwiki.rendering.block.Block;
    +
    +import com.xpn.xwiki.objects.BaseObject;
    +import com.xpn.xwiki.objects.PropertyInterface;
    +
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.PARAMETER_DEFAULT_VALUE_PROPERTY;
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.PARAMETER_TYPE_PROPERTY;
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.PARAMETER_TYPE_WIKI;
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.WIKI_MACRO_PARAMETER_CLASS;
    +
    +/**
    + * Required rights analyzer for {@code XWiki.WikiMacroParameterClass}.
    + *
    + * @version $Id$
    + * @since 17.0.0
    + * @since 16.10.3
    + * @since 16.4.7
    + */
    +@Component
    +@Singleton
    +@Named(WIKI_MACRO_PARAMETER_CLASS)
    +public class WikiMacroParameterObjectRequiredRightAnalyzer implements RequiredRightAnalyzer<BaseObject>
    +{
    +    @Inject
    +    private ObjectPropertyRequiredRightAnalyzer propertyRequiredRightAnalyzer;
    +
    +    @Override
    +    public List<RequiredRightAnalysisResult> analyze(BaseObject object) throws RequiredRightsException
    +    {
    +        List<RequiredRightAnalysisResult> results =
    +            new ArrayList<>(this.propertyRequiredRightAnalyzer.analyzeAllProperties(object));
    +        String type = object.getStringValue(PARAMETER_TYPE_PROPERTY);
    +        try {
    +            // Only check types that contain "<" to avoid parsing types that cannot be the list block type.
    +            if (PARAMETER_TYPE_WIKI.equals(type) || (StringUtils.contains(type, "<") && Block.LIST_BLOCK_TYPE.equals(
    +                ReflectionUtils.unserializeType(type, Thread.currentThread().getContextClassLoader()))))
    +            {
    +                String content = object.getStringValue(PARAMETER_DEFAULT_VALUE_PROPERTY);
    +                PropertyInterface defaultField = object.getField(PARAMETER_DEFAULT_VALUE_PROPERTY);
    +                results.addAll(this.propertyRequiredRightAnalyzer.analyzeWikiContent(object, content,
    +                    defaultField.getReference()));
    +            }
    +        } catch (ClassNotFoundException e) {
    +            // Ignore an unknown parameter type as it can't be the wiki parameter type.
    +        }
    +
    +        return results;
    +    }
    +}
    
  • xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-wikimacro/xwiki-platform-rendering-wikimacro-store/src/main/resources/META-INF/components.txt+1 0 modified
    @@ -7,3 +7,4 @@ org.xwiki.rendering.wikimacro.internal.WikiMacroClassDocumentInitializer
     org.xwiki.rendering.wikimacro.internal.WikiMacroContentMacro
     org.xwiki.rendering.wikimacro.internal.WikiMacroParameterClassDocumentInitializer
     org.xwiki.rendering.wikimacro.internal.WikiMacroParameterMacro
    +org.xwiki.rendering.wikimacro.internal.WikiMacroParameterObjectRequiredRightAnalyzer
    
  • xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-wikimacro/xwiki-platform-rendering-wikimacro-store/src/test/java/org/xwiki/rendering/wikimacro/internal/DefaultWikiMacroTest.java+21 0 modified
    @@ -707,4 +707,25 @@ void wikimacroparameterWhenInRawBlock() throws Exception
     
             assertEquals(expect, printer.toString());
         }
    +
    +    @Test
    +    void wikiMacroParameterWithDefaultValueContext() throws Exception
    +    {
    +        String defaultValue = "{{velocity}}$xcontext.sdoc{{/velocity}}";
    +        List<WikiMacroParameterDescriptor> parameterDescriptors = List.of(new WikiMacroParameterDescriptor("param",
    +            "Test parameter", false, defaultValue, Block.LIST_BLOCK_TYPE));
    +
    +        registerWikiMacro("defaultmacro", "{{wikimacroparameter name=\"param\"/}}", Syntax.XWIKI_2_1,
    +            parameterDescriptors);
    +
    +        Converter converter = this.componentManager.getInstance(Converter.class);
    +
    +        DefaultWikiPrinter printer = new DefaultWikiPrinter();
    +        converter.convert(
    +            new StringReader("{{defaultmacro /}} {{defaultmacro param=\"Outside: %s\" /}}".formatted(defaultValue)),
    +            Syntax.XWIKI_2_1, Syntax.PLAIN_1_0, printer);
    +
    +        assertEquals("space.macroPage Outside: sspace.sdoc", printer.toString());
    +
    +    }
     }
    
  • xwiki-platform-core/xwiki-platform-rendering/xwiki-platform-rendering-wikimacro/xwiki-platform-rendering-wikimacro-store/src/test/java/org/xwiki/rendering/wikimacro/internal/WikiMacroParameterObjectRequiredRightAnalyzerTest.java+106 0 added
    @@ -0,0 +1,106 @@
    +/*
    + * 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.rendering.wikimacro.internal;
    +
    +import java.util.List;
    +
    +import org.junit.jupiter.params.ParameterizedTest;
    +import org.junit.jupiter.params.provider.NullSource;
    +import org.junit.jupiter.params.provider.ValueSource;
    +import org.mockito.Mock;
    +import org.xwiki.platform.security.requiredrights.RequiredRightAnalysisResult;
    +import org.xwiki.platform.security.requiredrights.internal.analyzer.ObjectPropertyRequiredRightAnalyzer;
    +import org.xwiki.test.junit5.mockito.ComponentTest;
    +import org.xwiki.test.junit5.mockito.InjectMockComponents;
    +import org.xwiki.test.junit5.mockito.MockComponent;
    +
    +import com.xpn.xwiki.objects.BaseObject;
    +import com.xpn.xwiki.objects.PropertyInterface;
    +
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.mockito.Mockito.any;
    +import static org.mockito.Mockito.mock;
    +import static org.mockito.Mockito.never;
    +import static org.mockito.Mockito.verify;
    +import static org.mockito.Mockito.when;
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.PARAMETER_DEFAULT_VALUE_PROPERTY;
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.PARAMETER_TYPE_PROPERTY;
    +import static org.xwiki.rendering.wikimacro.internal.WikiMacroConstants.PARAMETER_TYPE_WIKI;
    +
    +/**
    + * Unit tests for {@link WikiMacroParameterObjectRequiredRightAnalyzer}.
    + *
    + * @version $Id$
    + */
    +@ComponentTest
    +class WikiMacroParameterObjectRequiredRightAnalyzerTest
    +{
    +    @InjectMockComponents
    +    private WikiMacroParameterObjectRequiredRightAnalyzer analyzer;
    +
    +    @MockComponent
    +    private ObjectPropertyRequiredRightAnalyzer propertyRequiredRightAnalyzer;
    +
    +    @Mock
    +    private BaseObject baseObject;
    +
    +    @Mock
    +    private PropertyInterface propertyInterface;
    +
    +    @ParameterizedTest
    +    @ValueSource(strings = { PARAMETER_TYPE_WIKI, "java.util.List<org.xwiki.rendering.block.Block>" })
    +    void analyzeWithWikiParameterType(String type) throws Exception
    +    {
    +        when(this.baseObject.getStringValue(PARAMETER_TYPE_PROPERTY)).thenReturn(type);
    +        String defaultValue = "wiki content";
    +        when(this.baseObject.getStringValue(PARAMETER_DEFAULT_VALUE_PROPERTY)).thenReturn(defaultValue);
    +        when(this.baseObject.getField(PARAMETER_DEFAULT_VALUE_PROPERTY)).thenReturn(this.propertyInterface);
    +        RequiredRightAnalysisResult allPropertiesResult = mock();
    +        when(this.propertyRequiredRightAnalyzer.analyzeAllProperties(this.baseObject))
    +            .thenReturn(List.of(allPropertiesResult));
    +        RequiredRightAnalysisResult wikiContentResult = mock();
    +        when(this.propertyRequiredRightAnalyzer.analyzeWikiContent(this.baseObject, defaultValue,
    +            this.propertyInterface.getReference())).thenReturn(List.of(wikiContentResult));
    +
    +        List<RequiredRightAnalysisResult> results = this.analyzer.analyze(this.baseObject);
    +
    +        assertEquals(List.of(allPropertiesResult, wikiContentResult), results);
    +        verify(this.propertyRequiredRightAnalyzer).analyzeAllProperties(this.baseObject);
    +        verify(this.propertyRequiredRightAnalyzer).analyzeWikiContent(this.baseObject, defaultValue,
    +            this.propertyInterface.getReference());
    +    }
    +
    +    @ParameterizedTest
    +    @ValueSource(strings = { "java.util.List", "unknown" })
    +    @NullSource
    +    void analyzeWithNonWikiParameterType(String parameterType) throws Exception
    +    {
    +        when(this.baseObject.getStringValue(PARAMETER_TYPE_PROPERTY)).thenReturn(parameterType);
    +        RequiredRightAnalysisResult result = mock();
    +        when(this.propertyRequiredRightAnalyzer.analyzeAllProperties(this.baseObject)).thenReturn(List.of(result));
    +
    +        List<RequiredRightAnalysisResult> results = this.analyzer.analyze(this.baseObject);
    +
    +        assertEquals(List.of(result), results);
    +        verify(this.propertyRequiredRightAnalyzer).analyzeAllProperties(this.baseObject);
    +        verify(this.propertyRequiredRightAnalyzer, never()).analyzeWikiContent(any(), any(), any());
    +        verify(this.baseObject, never()).getStringValue(PARAMETER_DEFAULT_VALUE_PROPERTY);
    +    }
    +}
    
  • xwiki-platform-core/xwiki-platform-security/xwiki-platform-security-requiredrights/xwiki-platform-security-requiredrights-default/src/main/java/org/xwiki/platform/security/requiredrights/internal/analyzer/ObjectPropertyRequiredRightAnalyzer.java+10 1 modified
    @@ -223,7 +223,16 @@ public List<RequiredRightAnalysisResult> analyzeVelocityScriptValue(String value
             return result;
         }
     
    -    private List<RequiredRightAnalysisResult> analyzeWikiContent(BaseObject object, String value,
    +    /**
    +     * Analyze the given wiki content in a property of the object.
    +     *
    +     * @param object the object to which the property belongs, used for getting the syntax and document reference
    +     * @param value the value with the wiki content
    +     * @param reference the reference of the property
    +     * @return the analysis results
    +     * @throws RequiredRightsException if an error occurs during the analysis
    +     */
    +    public List<RequiredRightAnalysisResult> analyzeWikiContent(BaseObject object, String value,
             EntityReference reference)
             throws RequiredRightsException
         {
    

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.