CVEReports
CVEReports

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

Product

  • Home
  • 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-25958

The Cube Root of Chaos: Smuggling Admin Privileges via WebSocket Pollution

Alon Barad
Alon Barad
Software Engineer

Feb 10, 2026·6 min read·44 visits

Executive Summary (TL;DR)

An authenticated attacker can escalate privileges by injecting a `securityContext` object into WebSocket messages or triggering a race condition in the API gateway. This allows bypassing Row-Level Security (RLS) and multi-tenant isolation, granting full admin access or data visibility across tenants.

Cube (formerly Cube.js) is the self-proclaimed 'semantic layer' for building data applications—a fancy way of saying it sits between your messy SQL databases and your pretty frontend charts. In versions prior to 1.5.13, Cube suffered from a catastrophic logic error in its WebSocket gateway and async handling. By simply asking nicely (read: injecting a JSON object), a low-privileged user could override their own security context. Even worse, a race condition in the promise chain allowed user contexts to 'bleed' into one another, meaning your request for 'My Sales' might accidentally return 'competitor_sales' if the server was busy enough. This is a classic case of trusting client input combined with the distinct misery of Node.js event loop management.

The Hook: The Semantic Layer Cake

In modern data stacks, 'Semantic Layers' are the new hotness. They act as the single source of truth, translating abstract business logic (like 'Revenue') into concrete SQL queries. Cube is the leader in this space. It handles authentication, caching, and query orchestration. Ideally, it's the bouncer at the club, checking IDs and ensuring you only sit at the table you paid for.

But here's the thing about bouncers: if they are distracted or easily bribed, the whole security model collapses. Cube relies heavily on 'Security Contexts'—objects defining who you are and what you can see (e.g., tenant_id: 123). This context is usually derived from a cryptographically signed JWT. You trust the JWT, you trust the context.

CVE-2026-25958 reveals that Cube didn't just trust the JWT. It also trusted the WebSocket packet you just sent it. It’s the equivalent of the bouncer checking your ID, then asking, 'And what VIP level would you like to be today?' and actually writing it down on your wristband.

The Flaw: Parameter Pollution & Broken Promises

This vulnerability is a two-headed beast. The first head is WebSocket Parameter Pollution. When you connect to Cube via WebSockets, you send JSON messages to trigger data loads. The backend logic took the user's provided message and merged it into the internal state. The developers failed to sanitize the input for reserved keys like securityContext.

If you sent a payload containing securityContext: { isAdmin: true }, the application effectively said, 'Sure, seems legit,' and merged that flag into your active session. This allows for trivial privilege escalation. You aren't cracking a password; you're just politely informing the server that you are, in fact, the boss.

The second head is a Race Condition in the Async Boundary. In packages/cubejs-api-gateway/src/gateway.ts, specific core methods (like meta and sql) invoked response callbacks without properly awaiting the result. In the Node.js event loop, this created a 'broken promise chain'.

Because the request context wasn't strictly bound to the execution scope of the database query, high-concurrency traffic could cause Context Bleeding. The security context of User A (an Admin) could leak into the response processing of User B (a Viewer), accidentally serving privileged data to the wrong socket.

The Code: The Smoking Gun

Let's look at the failure in the WebSocket handler. The code was iterating over the message parameters and blindly applying them. It lacked a 'strict' schema validation.

The Vulnerable Pattern (Simplified):

// Inside the WebSocket message handler
const processMessage = (message, connection) => {
  // message.params comes directly from the user
  const queryContext = {
    ...connection.userContext, // The real context from JWT
    ...message.params          // The untrusted input overwriting it
  };
  
  // queryContext now has user-injected 'isAdmin: true'
  return executeQuery(queryContext);
};

The Fix (Commit 6271520): The patch introduced zod schemas to strictly validate inputs. Instead of a spread operator that merges everything, the new code explicitly parses only allowed fields.

// The Fix: Strict Schema Validation
const LoadRequestSchema = z.object({
  query: QuerySchema,
  queryType: z.string().optional(),
  // securityContext is notably ABSENT from the allowed schema
});
 
const safeParams = LoadRequestSchema.parse(message.params);
// Now safeParams only contains what the devs intended.

Additionally, in gateway.ts (Commit 9e9f9d1), they had to fix the async bleeding.

Before:

this.loadImpl(options, (err, res) => {
   // Callback hell leading to context loss
});

After:

// Forcing the promise to resolve within the correct context scope
await this.loadImpl(options);

By forcing the await, the AsyncLocalStorage context remains consistent throughout the lifecycle of the request.

The Exploit: Becoming the Admin

To exploit this, you don't need fancy binary tools. You just need a WebSocket client and a valid low-privileged JWT. The goal is to bypass the Row-Level Security (RLS) that keeps tenants separate.

Step 1: Connect Establish a standard WebSocket connection to the Cube API. Authenticate with your low-privilege JWT.

Step 2: Craft the Payload Construct a load message. The documentation says you should send a query. The exploit says you should send a query AND a securityContext.

{
  "messageId": "1337",
  "method": "load",
  "params": {
    "query": {
      "measures": ["Orders.totalRevenue"],
      "dimensions": ["Orders.createdAt"]
    },
    "securityContext": {
      "u": {
        "id": 1,
        "roles": ["admin"],
        "tenantId": "*" 
      }
    }
  }
}

Step 3: Execution Send the JSON. The server deserializes the message. The securityContext provided in params overrides the one extracted from your JWT. Cube generates the SQL. Instead of WHERE tenant_id = 'your_id', it generates WHERE 1=1 (or whatever the admin rule is).

Step 4: Profit The server streams back the financial data for every tenant on the platform. You have successfully democratized the data, whether they wanted you to or not.

The Impact: Data Democratization (Involuntary)

This is a Critical Severity issue for any multi-tenant SaaS application using Cube. The impact is not just data leakage; it's total isolation failure.

  1. Row-Level Security Bypass: RLS is the only thing stopping Tenant A from seeing Tenant B's data. This exploit deletes that barrier.
  2. Privilege Escalation: If the application uses Cube's security context to determine UI features or write permissions (less common in Cube, but possible), an attacker gains administrative control.
  3. Metadata Injection: In some scenarios involving the order parameter (CWE-89), this could escalate further into blind SQL injection via the metadata generation layer.

The business impact? If you are a B2B SaaS provider, your customers' competitors just got access to their sales numbers. Trust is the first casualty.

The Fix: Closing the Window

Remediation is straightforward but urgent. You must upgrade the Cube core packages.

Action Items:

  1. Upgrade: Move to version 1.5.13, 1.4.2, or 1.0.14 immediately. These versions introduce the Zod schema validation that strips the malicious payload.
  2. Audit Logs: Check your WebSocket logs (if available) for requests containing the securityContext key in the parameters. This key should effectively never come from the client side.
  3. Disable WebSockets (Optional): If you aren't using real-time dashboards, turn them off via CUBEJS_WEB_SOCKETS=false. This reduces the attack surface significantly, as the REST API uses a different parsing path that was less susceptible to this specific pollution attack.

Developer Lesson: Never use the spread operator (...) on user input when building security contexts. It's concise, it's pretty, and it's dangerous.

Official Patches

CubePatch for WebSocket sanitization
CubePatch for Async Context Bleeding

Fix Analysis (2)

Technical Appendix

CVSS Score
7.7/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N

Affected Systems

Cube.js API GatewayCube Server CoreNode.js Semantic Layer implementations

Affected Versions Detail

Product
Affected Versions
Fixed Version
Cube
Cube Dev
0.27.19 - < 1.0.141.0.14
Cube
Cube Dev
1.1.0 - < 1.4.21.4.2
Cube
Cube Dev
1.5.0 - < 1.5.131.5.13
AttributeDetail
CWE IDCWE-807
Attack VectorNetwork (WebSocket)
CVSS7.7 (High)
ImpactPrivilege Escalation / Info Disclosure
Exploit StatusPoC Available
Fix ComplexityLow (Version Upgrade)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1078Valid Accounts
Defense Evasion
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-807
Reliance on Untrusted Inputs in a Security Decision

The application relies on untrusted inputs to make security decisions, specifically allowing client-side overriding of the security context.

Known Exploits & Detection

NVDAdvisory details indicating WebSocket parameter pollution.
GitHub Security AdvisoryTechnical description of the context bleeding and pollution vectors.

Vulnerability Timeline

Internal Fix for Native Layer Isolation
2025-12-04
Fix for WebSocket Sanitization
2025-12-09
Version 1.5.13 Released
2025-12-10
CVE-2026-25958 Published
2026-02-09

References & Sources

  • [1]GHSA Advisory
  • [2]NVD CVE-2026-25958

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.

More Reports

•about 12 hours ago•CVE-2026-115895
8.8

CVE-2026-115895: Code Injection via Unsanitized Import Alias in Happy DOM ECMAScript Module Compiler

CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.

Amit Schendel
Amit Schendel
6 views•10 min read
•about 13 hours ago•CVE-2026-115883
6.0

CVE-2026-115883: Cross-Namespace Access via Dot-Delimited Labels in LangGraph Postgres and SQLite Stores

An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.

Amit Schendel
Amit Schendel
7 views•9 min read
•about 14 hours ago•CVE-2026-115886
6.5

CVE-2026-115886: Unauthenticated Server-Side Request Forgery and Unsafe Reflection in MLflow Scorer Evaluation Endpoints

CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.

Alon Barad
Alon Barad
7 views•10 min read
•about 15 hours ago•CVE-2026-113872
7.5

CVE-2026-113872: Unauthenticated Process Crash in Express Multer via Late Busboy Stream Resumption

CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.

Amit Schendel
Amit Schendel
6 views•12 min read
•about 16 hours ago•CVE-2026-115897
2.1

CVE-2026-115897: Cross-Site Scripting via Function Body Boundary Bypass in serialize-javascript

CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.

Amit Schendel
Amit Schendel
6 views•13 min read
•about 17 hours ago•CVE-2026-109841
5.9

CVE-2026-109841: Subresource Integrity Verification Bypass in Node.js Undici

CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.

Alon Barad
Alon Barad
8 views•9 min read