Feb 22, 2026·7 min read·2 visits
Unauthenticated attackers can use the `extraFields` parameter in the XWiki Full Calendar Macro (< 2.4.6) to request arbitrary document properties. This allows leaking sensitive user data like emails. The fix implements a type-based blacklist.
A technical deep-dive into an Information Disclosure vulnerability in the XWiki Full Calendar Macro. The flaw allows unauthenticated attackers to leverage the `extraFields` parameter in the `Calendar.JSONService` to retrieve arbitrary properties from wiki documents, effectively turning a mundane calendar feature into a data exfiltration pipeline.
In the grand hierarchy of 'things that keep security engineers awake at night,' a calendar widget usually ranks somewhere between 'the cafeteria menu' and 'the font size on the 404 page.' But that is exactly where the danger lies. We spend so much time fuzzing complex authentication flows and deserialization gadgets that we often overlook the mundane extensions that glue the enterprise together.
Meet the XWiki Full Calendar Macro. It’s a staple extension for XWiki, designed to fetch event data from wiki pages and render it nicely in a grid. It does exactly what it says on the tin. However, under the hood, it relies heavily on Velocity, a Java-based template engine that XWiki uses for scripting. Velocity is powerful—it can access Java objects, query the database, and render dynamic content. If you give a user control over Velocity inputs without strict boundaries, you aren't building a web app; you're building a remote shell with extra steps.
CVE-2025-65090 isn't a complex memory corruption bug. It’s a logic flaw born from a developer trying to be helpful. They wanted to make the calendar flexible, allowing the frontend to request specific data fields. Unfortunately, they implemented this flexibility with the security posture of a wet paper towel, effectively trusting the client to dictate what data the server should surrender.
The vulnerability resides in a specific service page: Calendar.JSONService. This endpoint exists to serve JSON data to the frontend JavaScript calendar. To populate the calendar events, the service iterates over wiki documents that represent events. But here is the kicker: different organizations store events differently. Some might want to show a 'Location' field, others a 'Host' field, and others might want to display the 'Catering Menu'.
To accommodate this, the developers introduced an input parameter called extraFields. The logic was simple: the client sends a list of field names it wants, and the server fetches the values for those fields from the document and adds them to the JSON response.
The fatal flaw? Zero validation.
The code didn't check if the requested field was part of the 'Event' class. It didn't check if the user had permission to view that specific field. It simply took the string provided by the user, looked up that property on the document, and returned the value. In the security world, we call this an Insecure Direct Object Reference (IDOR) mixed with Mass Assignment concepts. It is the digital equivalent of a bank teller asking, 'What else would you like from the vault today?' and handing over whatever you name, provided you spell it correctly.
Let's look at the 'smoking gun' code in Calendar/JSONService.xml. Before the patch, the loop handling these extra fields was terrifyingly trusting. It essentially grabbed the parameter and passed it straight into the $itemdoc.getValue() or $itemdoc.display() methods.
#set ($description = $itemdoc.getValue($extraFields[0].trim())) #set ($xdom = $services.rendering.parse($description, 'xwiki/2.1')) #set ($description = $services.rendering.render($xdom, 'plain/1.0'))
#set ($currentResult.location = $itemdoc.display($extraFields[1].trim())) #set ($currentResult.status = $itemdoc.display($extraFields[2].trim()))
Do you see the issue? `$extraFields[0]` comes directly from the URL. If I pass `email` as the first extra field, `$itemdoc.getValue('email')` executes. If the document happens to be a User Profile (which are just XWiki pages with an `XWikiUsers` object), the variable `$description` now contains the user's email address. The code then happily packages this up and sends it back to me.
This is a classic case of **implicit trust**. The developer assumed `extraFields` would only ever contain harmless strings like 'location' or 'description'. They failed to account for a malicious user who knows the internal schema of XWiki classes.
Exploiting this is trivially easy. We don't need a compiler, we don't need shellcode, and we certainly don't need authentication if the wiki is public. We just need a web browser or curl.
Calendar.JSONService endpoint.extraFields parameter.GET /xwiki/bin/get/Calendar/JSONService?outputSyntax=plain&extraFields[0]=email&extraFields[1]=password&calendarName=UserDirectory(Note: In reality, fetching the password field usually returns a hash, which is still bad, but not plaintext. However, the email field is often the golden ticket for phishing campaigns or credential stuffing).
While the CVSS score is a moderate 5.3 (Medium), don't let that fool you. Context is king. In a corporate intranet, this vulnerability is a privacy nightmare.
Data Leakage: The most immediate impact is the leakage of Personally Identifiable Information (PII). Emails, phone numbers, and physical addresses stored in user profiles are up for grabs. If the XWiki instance is used for HR or project management, the extraFields could be used to extract sensitive project details, budget codes, or internal comments that were never meant to be public.
Social Engineering Prerequisite: With a list of valid emails and their associated full names (which are often the document titles), an attacker has everything they need to launch a highly targeted spear-phishing campaign. 'Hey [Real Name], please update your password on the [Real Wiki Name] portal.'
Low Barrier to Entry: The complexity of this attack is effectively zero. It requires no specialized tools. A junior analyst with a browser dev console can discover and exploit this in minutes. That low barrier increases the likelihood of exploitation significantly.
The remediation provided in version 2.4.6 is... interesting. Instead of whitelisting allowed fields (which would be the robust 'secure by design' approach), the developers implemented a type-based blacklist.
They introduced a new macro, #getField, which inspects the type of the property being requested:
#macro (getField $classField $useDisplay)
#set ($propertyClass = $itemdoc...getPropertyClass())
#if ($propertyClass)
## The Gatekeeper Logic
#if (($propertyClass.getClassType() != 'Email' || !$services.mail.general.shouldObfuscate()) &&
$propertyClass.getClassType() != "Password")
## Allow access
#else
## Log warning and deny
$services.logging.getLogger(...).warn("Forbidden access attempt")
#end
#end
#endThis patch specifically blocks properties of type Password and conditionally blocks Email (only if the administrator has enabled global mail obfuscation).
The Problem: Blacklists are historically fragile. This fix assumes that Password and Email are the only sensitive things in your database. What if you have a custom field called SocialSecurityNumber stored as a generic String? The blacklist won't catch it. The exploit would still work for any field that isn't explicitly typed as Email or Password.
Mitigation Advice: Patching to 2.4.6 stops the immediate bleeding of credentials and emails. However, if you store other sensitive data in XWiki objects, you should audit your Calendar.JSONService usage or restrict view permissions on the sensitive documents themselves. Do not rely on this macro to protect data types it doesn't know about.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
XWiki Full Calendar Macro XWiki | < 2.4.6 | 2.4.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-200 |
| Attack Vector | Network |
| CVSS v3.1 | 5.3 (Medium) |
| Impact | Information Disclosure (Low Confidentiality Impact) |
| Exploit Status | PoC Possible (Trivial) |
| Authentication | None (Publicly Exploitable if wiki is public) |
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.