CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-65091
10.00.20%

Calendar of Doom: A Critical HQL Injection in XWiki

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 22, 2026·7 min read·11 visits

PoC Available

Executive Summary (TL;DR)

The XWiki Full Calendar Macro (< 2.4.5) contains a trivial HQL injection. Attackers can pass a full database query via the URL parameters, executing it with the privileges of the script author (often Admin). This grants read access to all data, including credentials.

A 10.0 Critical vulnerability in the XWiki Full Calendar Macro allows unauthenticated attackers to execute arbitrary Hibernate Query Language (HQL) commands. By manipulating the 'sql', 'fromsql', or 'wheresql' parameters in the Calendar.JSONService page, attackers can bypass security controls, exfiltrate the entire wiki database, or potentially deny service to the host. The flaw stems from direct concatenation of user input into database queries, essentially providing a remote database shell to anyone who asks nicely.

The Hook: When Calendars Attack

We often ignore the little things. The plugins, the macros, the 'quality of life' add-ons that make enterprise software bearable. In the XWiki ecosystem, the Full Calendar Macro is one such tool—a simple utility to display events. But as with many innocent-looking features, it harbored a dark secret. It didn't just display events; it acted as an open gateway to the underlying database.

This vulnerability, tracked as CVE-2025-65091, is a perfect example of what happens when convenience overrides security. It isn't a complex memory corruption bug or a subtle race condition. It is a logic flaw so glaring that it feels almost polite. The application essentially asked the user, "Hey, what database query would you like me to run for you today?" and then dutifully executed it.

Because XWiki relies heavily on HQL (Hibernate Query Language), this isn't just about reading calendar entries. An injection here allows an attacker to traverse the object graph, accessing user profiles, password hashes (if stored), and proprietary documentation. Worse, it was exploitable by unauthenticated users, earning it the rare and terrifying CVSS 10.0 score. If you had this macro installed, your wiki was effectively public.

The Flaw: A Masterclass in Bad Practice

The root cause of this vulnerability lies in the file Calendar.JSONService.xml. This script is responsible for fetching event data to populate the calendar UI. To do this, it constructs a database query. In a secure application, this would be done using a fixed query with parameterized inputs. In the vulnerable version, it was done using string concatenation of the worst kind.

The developers implemented a feature that allowed the frontend to specify exactly how to filter data. They exposed parameters like request.sql, request.fromsql, and request.wheresql. If the sql parameter was present, the code would simply take that string and treat it as the entire HQL query.

Think about that for a second. The code explicitly checked: "Did the user provide a full SQL command? If yes, let's run that instead of our logic." It is the web application equivalent of leaving the keys in the ignition with the engine running and a sign on the dashboard that says "Free Car."

Even if the sql parameter wasn't used, the code blindly concatenated fromsql and wheresql into the query string. This meant that even without replacing the whole query, an attacker could inject JOIN statements to link sensitive tables or modify the WHERE clause to bypass visibility checks. It is a textbook Injection flaw, mapped to CWE-89, but operating at the ORM level.

The Code: The Smoking Gun

Let's look at the vulnerable Velocity code. This is where the magic (and the horror) happens.

The Vulnerable Code (Pre-Patch):

#if ("$!\{request.sql\}" != '')
  ## The developer trusts the user implicitly here.
  #set ($hql = $request.sql)
#else
  ## Even the fallback is dangerous.
  #set ($hql =", BaseObject as obj $!\{request.fromsql\} where doc.fullName=obj.name and obj.className='$\{request.classname\}' $!\{request.wheresql\}")
#end
...

The execution triggered with high privileges

#foreach ($item in $services.query.hql($hql).execute())


The variable `$request.sql` is taken directly from the URL query string. If I send `?sql=select...`, the variable `$hql` becomes my query. The `$services.query.hql($hql).execute()` line then runs it against the database.

**The Fix (Version 2.4.5):**

The developers stripped out the direct override and added a critical permission drop.

```velocity

No more $request.sql check.

#set ($hqlStatement =", BaseObject as obj $!{request.fromsql} where doc.fullName=obj.name and obj.className=:classname $!{request.wheresql}") ...

CRITICAL: Drop permissions to the current user (Guest)

#set ($discard = $xcontext.dropPermissions())

Bind the classname parameter instead of interpolating it

#foreach ($item in $services.query.hql($hqlStatement).bindValue("classname", "$!{request.classname}").addFilter('currentlanguage').execute())


Notice two things: First, the ability to completely replace the query via `sql` is gone. Second, and arguably more importantly, `$xcontext.dropPermissions()` is called. In XWiki, scripts often run with the permissions of the *author* (usually an Admin who installed the extension). `dropPermissions()` forces the script to run with the permissions of the *requestor*. If you are an unauthenticated attacker, you are now just "Guest," and you can't query sensitive tables even if you manage to inject SQL.

The Exploit: Stealing the Kingdom

Exploiting this is trivially easy. You don't need Burp Suite; you just need a web browser. The attack vector targets the JSONService which is publicly accessible.

Scenario 1: The Full Dump

An attacker wants to list all documents in the wiki to map out the internal structure.

URL: http://target-wiki/xwiki/bin/view/Calendar/JSONService?sql=select+doc.fullName,+doc.title+from+XWikiDocument+doc

The server sees the sql parameter, ignores its internal logic, and executes the HQL: select doc.fullName, doc.title from XWikiDocument doc. The JSON response will kindly return every document title in the system.

Scenario 2: Credential Hunting

XWiki stores user data in objects. While password hashes might be salted, getting the list of usernames and their metadata is a goldmine for social engineering or brute force.

URL: http://target-wiki/xwiki/bin/view/Calendar/JSONService?sql=select+obj.name+from+BaseObject+obj+where+obj.className='XWiki.XWikiUsers'

Scenario 3: The 'Re-Exploit' (Post-Patch Bypass Attempt)

Look closely at the patched code. The developer still includes $!{request.fromsql} and $!{request.wheresql} in the query string!

#set ($hqlStatement =", BaseObject as obj $!{request.fromsql} ... $!{request.wheresql}")

While they bound :classname and removed request.sql, injection is technically still possible in the FROM and WHERE clauses. However, because of $xcontext.dropPermissions(), the query runs as 'Guest'. So, while I can still inject HQL syntax (e.g., ?fromsql=, XWikiDocument as doc), I can only retrieve data that 'Guest' is allowed to see. The exploit is neutered not by fixing the injection fully, but by stripping the privileges required to make the injection dangerous. It's a functional fix, but a dirty one from a code purity standpoint.

The Impact: Why 10.0?

A CVSS score of 10.0 is reserved for the absolute worst-case scenarios. Why did a calendar plugin merit this?

  1. Scope Change (S:C): The vulnerability allows access to the underlying database (Hibernate context), which impacts the entire XWiki instance, not just the calendar component.
  2. No Privileges Required (PR:N): You don't need an account. If the wiki is on the internet, you can hit it.
  3. Confidentiality, Integrity, Availability (C:H, I:H, A:H):
    • Confidentiality: You can read any data the script author (Admin) could access.
    • Integrity: While HQL is mostly for querying, some configurations or advanced HQL injection techniques (like calling update statements if the transaction context allows) could corrupt data.
    • Availability: A complex query (Cartesian product) injected via sql could lock up the database, causing a Denial of Service.

Essentially, this flaw turns a collaboration tool into a data exfiltration pipe. For organizations using XWiki as an internal knowledge base, this exposes everything from network diagrams to HR policies to the public internet.

The Fix: Closing the Window

If you are running org.xwiki.contrib:macro-fullcalendar versions older than 2.4.5, you are vulnerable. The remediation is straightforward: Update the extension immediately.

If you cannot update for some reason (perhaps you've forked the code), you must manually patch Calendar.JSONService.xml. The most critical change is ensuring that the script drops permissions before executing any query that touches user input.

Remediation Checklist:

  1. Upgrade macro-fullcalendar to 2.4.5+ via the Extension Manager.
  2. Verify the fix by checking Calendar.JSONService source code for $xcontext.dropPermissions().
  3. Audit Logs: Check your access logs for requests to JSONService containing query parameters like select, from, or join. If you see these, you have likely already been scanned or compromised.

Since this exploit leaves no binary artifacts (it's just a web request), log analysis is your only hope for forensic confirmation.

Official Patches

XWikiGitHub Commit fixing the issue
GHSAGitHub Security Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
10.0/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
0.20%
Top 58% most exploited

Affected Systems

XWiki installations using macro-fullcalendar < 2.4.5XWiki Enterprise (if macro is bundled/installed)XWiki Standard Flavor (if macro is bundled/installed)

Affected Versions Detail

Product
Affected Versions
Fixed Version
macro-fullcalendar
XWiki Contrib
< 2.4.52.4.5
AttributeDetail
CWE IDCWE-89 (SQL Injection)
CVSS v3.110.0 (Critical)
Attack VectorNetwork (HQL Injection via GET parameters)
Exploit StatusPoC Available / Trivial
PrivilegesNone (Unauthenticated)
Patch Commit5fdcf06a05015786492fda69b4d9dea5460cc994

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059Command and Scripting Interpreter
Execution
T1087Account Discovery
Discovery
CWE-89
Improper Neutralization of Special Elements used in an SQL Command

Vulnerability Timeline

Patch committed to GitHub repository
2025-07-04
CVE-2025-65091 Published
2026-01-10
GHSA Advisory Released
2026-01-10

References & Sources

  • [1]GHSA Advisory
  • [2]XWiki JIRA Ticket (Generic Reference)

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.