Calendar Leaks: When 'Extra Fields' Reveal Your Secrets
Jan 11, 2026·6 min read
Executive Summary (TL;DR)
A Classic 'Insecure Direct Object Reference' style flaw in a Velocity script allowed attackers to request specific database fields (like emails or internal metadata) through a calendar widget's backend service. The fix involves a blacklist, but the underlying design remains permissive.
The XWiki Full Calendar Macro allowed unauthenticated users to query arbitrary object properties via the JSON service, bypassing UI restrictions and leaking potentially sensitive data.
The Hook: Macros, Velocity, and Open Windows
XWiki is a beast of a platform. It's not just a wiki; it's a structured data engine powered by Java and Velocity. One of its strengths is 'Macros'—little plugins that make pages dynamic. The Full Calendar Macro (macro-fullcalendar) is one such tool, designed to plot wiki objects (like tasks or events) onto a nice UI.
To make the UI snappy, the macro relies on a backend endpoint: Calendar.JSONService. This service listens for AJAX requests and spits out event data. It’s meant to be a helpful waiter, fetching exactly what the frontend needs to render the calendar.
The problem? This waiter didn't care who was asking or what they were ordering. If you asked for the standard event title, fine. If you asked for the server's hidden metadata or user emails, the waiter would just shrug and hand it over. It's the classic tragedy of "Client-Side Trust"—assuming that because the UI only asks for safe data, an attacker won't ask for the unsafe stuff manually.
The Flaw: Trusting the 'extraFields'
The vulnerability lived in macro-fullcalendar-ui/src/main/resources/Calendar/JSONService.xml. This file handles the logic for retrieving event data. To allow for customization, the developers implemented a feature called extraFields. This parameter allowed the frontend to say, "Hey, while you're grabbing the event title, also grab these other properties for me."
Here is where the logic went off the rails. The code took the user-supplied list of field names and directly fed them into the $itemdoc.getValue() method. There was no allowlist. There was no check to see if the field was marked as 'internal' or 'sensitive'.
Effectively, this turned the JSONService into a generic database proxy. If you had 'View' rights on a document (which Guests often do on public wikis), you could bypass the carefully crafted HTML views—which might hide sensitive fields—and just ask the API for the raw data directly. It’s an Access Control bypass via the presentation layer.
The Code: The Smoking Gun
Let's look at the vulnerable Velocity code (simplified for clarity). It reads like a "How To" for Insecure Direct Object References (IDOR).
Pre-patch logic in Calendar/JSONService.xml
#if ($extraFields.size() > 0)
Take the first extra field requested by the user
#set ($description = $itemdoc.getValue($extraFields[0].trim()))
Render it and send it back
#set ($currentResult.description = $description)
Do the same for other slots
#set ($currentResult.location = $itemdoc.display($extraFields[1].trim())) #end
Do you see the lack of friction? The code just blindly executes `$itemdoc.getValue()`. If `$extraFields[0]` is "email", you get the email. If it's "password" (and you are querying a User object), you get the hash.
The fix (Commit `25bc14c1`) introduces a gatekeeper macro called `#getField`. Instead of grabbing the value immediately, it checks the **Class Type** of the property.
```velocity
Post-patch logic
#macro (getField $classField $useDisplay)
Get the property definition to check its type
#set ($propertyClass = $itemdoc.getFirstObject($classField).getProperty($classField).getPropertyClass())
The BLACKLIST approach
#if (($propertyClass.getClassType() != 'Email' || !$services.mail.general.shouldObfuscate()) && $propertyClass.getClassType() != "Password")
If it's not a password, and not an obfuscated email, return it
#set ($result = $itemdoc.getValue($classField)) #else
Log the intrusion attempt
$services.logging.getLogger(...).warn("Forbidden access attempt") #end #end
While this stops the bleeding for the most obvious targets (Passwords and Emails), it is a **reactive blacklist**. It does not inherently trust-verify; it just blocks specific bad things.
The Exploit: Scraping the Database
Exploiting this is trivially easy. You don't need special tools; a web browser or curl is enough. The goal is to identify a class you want to inspect (like XWiki.XWikiUsers) and then iterate through the documents.
Step 1: Reconnaissance
First, identify if the wiki is running the Full Calendar Macro. Look for pages referencing Calendar.JSONService.
Step 2: Crafting the Payload Construct a GET request. Let's say we want to dump user emails and phone numbers (assuming a custom field 'phone' exists).
GET /xwiki/bin/view/Calendar/JSONService?outputSyntax=plain&classname=XWiki.XWikiUsers&extraFields=email,phone
Step 3: The Response
The server processes the request, finds all objects of type XWiki.XWikiUsers, and for each one, extracts the email and phone properties, returning them in a structured JSON array intended for the calendar display.
Re-exploitation Potential:
Because the fix relies on checking if a field is explicitly of type Password or Email, an attacker can still retrieve sensitive data stored in generic field types. For example, if a developer stored an API Key in a standard String field or a TextArea, the new patch will not block it. The macro will see it as a safe text field and return the data. The vulnerability is patched for the specific CVE report, but the design flaw (arbitrary property retrieval) persists for non-blacklisted types.
The Impact: Why should we panic?
The impact here is primarily Confidentiality Loss. While this isn't Remote Code Execution (RCE), it is a high-value target for information gathering.
- PII Harvesting: Attackers can scrape email addresses, real names, and physical addresses from user profiles or custom employee directories hosted on the wiki.
- Infrastructure Leakage: Technical wikis often use custom classes to track servers, assets, or configurations. An attacker could request fields like
ip_address,internal_hostname, orpatch_levelto map out the internal network before launching a deeper attack. - Social Engineering: By correlating user activity (calendar events) with their personal details (leaked via this CVE), an attacker can craft highly convincing phishing campaigns.
The severity is tempered only by the fact that the attacker needs to know the names of the fields they are looking for. However, standard XWiki class definitions (XWiki.XWikiUsers, XWiki.XWikiRights) are public knowledge.
The Fix: Mitigation & Lessons
The immediate fix is to upgrade org.xwiki.contrib:macro-fullcalendar to version 2.4.6. This applies the property type check we discussed earlier.
For Administrators:
- Update: Apply the patch via the Extension Manager.
- Audit Permissions: Verify that
XWikiGuest(unauthenticated users) does not have view access to technical pages likeCalendar.JSONService. There is rarely a need for the public to query raw JSON services directly. - Email Obfuscation: Ensure that
$services.mail.general.shouldObfuscate()resolves to true in your configuration. The patch allows email leakage if the global obfuscation setting is turned off. It's a conditional fix.
For Developers: This vulnerability highlights the danger of 'Passthrough' APIs. Never create an endpoint that accepts a field name as a string and blindly invokes a getter for it. Always use Data Transfer Objects (DTOs) or explicit allowlists that define exactly which fields are safe to expose to the frontend.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
macro-fullcalendar XWiki Contrib | < 2.4.6 | 2.4.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-200 |
| CVSS Score | 5.3 (Medium) |
| Attack Vector | Network (AV:N) |
| EPSS Score | 0.00027 |
| Impact | Data Leakage / PII Exposure |
| Patch Status | Available (v2.4.6) |
MITRE ATT&CK Mapping
Exposure of Sensitive Information to an Unauthorized Actor
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.