VAITP Dataset

← Back to the dataset

CVE-2025-49581

XWiki: Macro parameter default value executes with elevated rights, allows code injection.

  • CVSS 8.7
  • CWE-94
  • Authentication, Authorization, and Session Management
  • Remote

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.

CVSS base score
8.7
Published
2025-06-13
OWASP
A03:2021-Injection
Orthogonal defect classification
Interface
Code defect classification
Incorrect Functionality
Category
Authentication, Authorization, and Session Management
Subcategory
Privilege Escalation
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
XWiki

Solution

Upgrade to XWiki 16.4.7, 16.10.3, or 17.0.0.

Vulnerable code sample

# This code simulates a vulnerable XWiki macro execution before the fix for CVE-2025-49581.
# It demonstrates how a crafted macro, when used with default parameter values,
# could execute code with elevated privileges (simulated here).
# NOTE: This is a simplified representation and doesn't replicate the full XWiki environment.

def vulnerable_macro(param1="default_value", param2="[[evaluate this]]"):
    """
    Simulates a vulnerable XWiki macro where the default value of a parameter
    containing wiki syntax (simulated by "[[evaluate this]]") is executed.
    """
    if param2 == "[[evaluate this]]":
        # Simulate execution of arbitrary code as the author of the page
        # containing the macro.  In a real XWiki context, this could be Groovy,
        # Python, or Velocity code.  Here, we simulate it with a print statement.
        print("[VULNERABILITY SIMULATION] Executing code with elevated privileges!")
        print("Param1 value:", param1)
        # In a real attack, this is where malicious code would be inserted.
    else:
        print("Macro executed with provided parameters.")
        print("Param1:", param1)
        print("Param2:", param2)

# Example usage:
# An attacker could craft a page with this macro and rely on the default value
# of 'param2' to execute their malicious code.

print("Using the macro with default parameters:")
vulnerable_macro() # Executes the 'evaluate this' code

print("\nUsing the macro with custom parameters:")
vulnerable_macro(param1="custom_value", param2="safe_value")  # Executes safely

Patched code sample

def execute_macro(macro_code, user_rights, is_default_value, macro_author_rights):
    """
    Executes a wiki macro with appropriate rights, mitigating CVE-2025-49581.

    Args:
        macro_code: The code to execute.
        user_rights: The rights of the user invoking the macro.
        is_default_value: True if the macro code comes from a default parameter value, False otherwise.
        macro_author_rights: The rights of the macro author.

    Returns:
        The result of the macro execution.
    """

    if is_default_value:
        # Execute with the rights of the macro author (fixed behavior)
        effective_rights = macro_author_rights
    else:
        # Execute with the rights of the user invoking the macro (original behavior)
        effective_rights = user_rights

    # Simulate rights check and execution
    if "programming" in effective_rights:
        # Secure execution:  Implement sandboxing, whitelisting, or other security measures
        # to prevent arbitrary code execution even with programming rights.
        # This is a simplified example; a real implementation would be much more complex.

        if "groovy" in macro_code.lower() or "python" in macro_code.lower() or "velocity" in macro_code.lower():

            # Simulate a very basic "safe" execution.  In reality, you would need a much
            # more robust sandboxing mechanism.
            print(f"Executing macro with {effective_rights} rights (safe execution): {macro_code}")
            # Replace this with actual sandboxed execution.
            result = "Macro executed successfully (simulated)." # Or an error, if execution failed

        else:
             print(f"Executing macro with {effective_rights} rights: {macro_code}")
             result = "Macro executed successfully (simulated)." # Or an error, if execution failed

    else:
        print(f"Executing macro with {effective_rights} rights: {macro_code}")
        result = "Macro executed successfully (simulated)."


    return result

# Example usage (simulating the patch)
if __name__ == '__main__':
    # Example scenario:
    user_rights = ["edit"] # User with edit rights
    macro_author_rights = ["programming"] # Macro author with programming rights
    macro_code = "Groovy code to access system files" # Vulnerable code example

    # Case 1: Macro code provided by the user directly
    result1 = execute_macro(macro_code, user_rights, False, macro_author_rights)
    print(f"Result 1: {result1}")

    # Case 2: Macro code is the default value of a parameter (CVE-2025-49581)
    result2 = execute_macro(macro_code, user_rights, True, macro_author_rights) # This line shows the fix
    print(f"Result 2: {result2}") # Now, the macro is executed with macro_author_rights

Payload

{{velocity}}
#set ($rt=$xwiki.getRuntime())
#set ($cmd='whoami')
#set ($process=$rt.exec($cmd))
$process.waitFor()
#set ($input=$process.getInputStream())
#set ($content=$xwiki.ss().getStreamAsString($input))
$content
{{/velocity}}

Cite this entry

@misc{vaitp:cve202549581,
  title        = {{XWiki: Macro parameter default value executes with elevated rights, allows code injection.
}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2025},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2025-49581},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-49581/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::