CVE-2025-65090

Calendar Leaks: When 'Extra Fields' Reveal Your Secrets

Amit Schendel
Amit Schendel
Senior Security Researcher

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.

  1. PII Harvesting: Attackers can scrape email addresses, real names, and physical addresses from user profiles or custom employee directories hosted on the wiki.
  2. Infrastructure Leakage: Technical wikis often use custom classes to track servers, assets, or configurations. An attacker could request fields like ip_address, internal_hostname, or patch_level to map out the internal network before launching a deeper attack.
  3. 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:

  1. Update: Apply the patch via the Extension Manager.
  2. Audit Permissions: Verify that XWikiGuest (unauthenticated users) does not have view access to technical pages like Calendar.JSONService. There is rarely a need for the public to query raw JSON services directly.
  3. 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 Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
EPSS Probability
0.03%
Top 93% most exploited

Affected Systems

XWiki Full Calendar Macro < 2.4.6XWiki installations allowing Guest view on macro pages

Affected Versions Detail

Product
Affected Versions
Fixed Version
macro-fullcalendar
XWiki Contrib
< 2.4.62.4.6
AttributeDetail
CWE IDCWE-200
CVSS Score5.3 (Medium)
Attack VectorNetwork (AV:N)
EPSS Score0.00027
ImpactData Leakage / PII Exposure
Patch StatusAvailable (v2.4.6)
CWE-200
Information Exposure

Exposure of Sensitive Information to an Unauthorized Actor

Vulnerability Timeline

Fix committed to repository
2025-08-06
CVE Published
2026-01-10

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.