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



GHSA-W9X9-J56R-H98R

GHSA-w9x9-j56r-h98r: Unauthenticated Confused Deputy Proxy in @eeacms/volto-chatbot

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 30, 2026·8 min read·3 visits

Executive Summary (TL;DR)

Versions 2.0.3 and earlier of `@eeacms/volto-chatbot` expose unauthenticated wildcard proxy routes that automatically attach server-side API keys to outgoing requests, allowing unauthenticated attackers to invoke arbitrary administrative endpoints on upstream Danswer and Halloumi backends.

The @eeacms/volto-chatbot package for Plone Volto contains an unauthenticated confused deputy vulnerability (CWE-862) in versions 2.0.3 and earlier. The package registers Express middleware on wildcard proxy routes (`**/_v1_da/**` and `**/_v1_ha/**`) without verifying client authentication or restricting target endpoints. When processing incoming HTTP requests, the middleware automatically attaches server-side administrative credentials before forwarding the requests to upstream Danswer (Onyx) or Halloumi (LLMGW) API servers. This allows unauthenticated network attackers to execute arbitrary administrative API calls against the backend infrastructure.

Vulnerability Overview

@eeacms/volto-chatbot is an add-on package for the Plone Volto React frontend framework that integrates AI conversational agents, specifically Danswer (now Onyx) and Halloumi (LLMGW). To facilitate communication between client browsers and backend AI services without exposing API credentials to the browser, the package implements server-side Express proxy middleware within the Volto Node.js server.

In versions 2.0.3 and earlier, this proxy layer exhibits a Missing Authorization vulnerability (CWE-862) operating as a confused deputy. The application registers wildcard routes (**/_v1_da/** and **/_v1_ha/**) that accept any HTTP method and path combination from unauthenticated users. The middleware strips the proxy prefix from the request URL, appends the remaining path directly to the configured upstream server URL, and injects the server's configured administrative API token or session cookie.

Because the middleware performs neither client authentication checks nor path allowlisting, any network actor capable of reaching the Volto web server can interact directly with the entirety of the upstream Danswer and Halloumi REST APIs. The requests arrive at the upstream API server bearing the Volto server's elevated credentials, bypassing upstream access controls.

Root Cause Analysis

The root cause of GHSA-w9x9-j56r-h98r is the combination of unrestricted URL path rewriting and unconditional credential injection inside the Express middleware functions located in src/middleware.js and src/halloumi/middleware.js. In src/index.js, the application registers the Danswer proxy handler using middleware.all('**/_v1_da/**', proxyMiddleware). The .all() method binds the handler to every HTTP verb, and the glob pattern matches any sub-path.

When a request enters the Danswer middleware (src/middleware.js), the code extracts the target API path by performing a direct string replacement on req.url, replacing the /_v1_da/ prefix with /. The resulting string is concatenated with the DANSWER_URL environment variable and /api. The middleware does not sanitize path traversal sequences, validate the target endpoint against a list of safe conversational APIs, or restrict the HTTP verb to read-only operations.

Following URL construction, the middleware retrieves authentication credentials configured in the server environment—either an API token via process.env.DANSWER_API_KEY or a cached authentication cookie derived from DANSWER_USERNAME and DANSWER_PASSWORD. These credentials are inserted into the outgoing request's Authorization or Cookie header.

An identical architectural flaw exists in the Halloumi proxy module (src/halloumi/middleware.js). That module intercepts requests matching /_v1_ha/, strips the prefix, attaches the LLMGW_TOKEN bearer token, and dispatches the request to LLMGW_URL. In both modules, the Node.js process acts as an unguarded gateway that lends its backend identity to anonymous callers.

Code Analysis

Prior to version 2.0.4, the request handling logic in src/middleware.js processed incoming URLs and dispatched them immediately to the upstream service. The vulnerable implementation lacked any validation logic between path extraction and upstream URL assembly:

// Vulnerable implementation in src/middleware.js (<= 2.0.3)
export default async function middleware(req, res, next) {
  // Directly rewrites any client-supplied path under /_v1_da/
  const path = req.url.replace('/_v1_da/', '/');
  const reqUrl = `${process.env.DANSWER_URL || ''}/api${path}`;
 
  const username = process.env.DANSWER_USERNAME;
  // ... attaches DANSWER_API_KEY or session cookie and calls fetch()

In commit a459b36dbd2c67e6397cc81910e27b9d611cca18, the maintainers remediated the vulnerability by introducing explicit endpoint and HTTP method allowlists (ALLOWED_PROXY_PATHS and ALLOWED_HALLOUMI_PATHS) alongside a validation helper function named isPathAllowed.

// Patched implementation in src/middleware.js (2.0.4)
const ALLOWED_PROXY_PATHS = [
  { path: '/persona', methods: ['GET'] },
  { pathPattern: /^\/persona\/\d+$/, methods: ['GET'] },
  { path: '/chat/create-chat-session', methods: ['POST'] },
  { path: '/chat/send-message', methods: ['POST'] },
  { path: '/chat/create-chat-message-feedback', methods: ['POST'] },
];
 
function isPathAllowed(strippedPath, method, allowedPaths) {
  // Strip query parameters before validating the path
  const cleanPath = strippedPath.split('?')[0];
  return allowedPaths.some(
    (entry) =>
      (entry.path === cleanPath ||
        (entry.pathPattern && entry.pathPattern.test(cleanPath))) &&
      entry.methods.includes(method),
  );
}
 
export default async function middleware(req, res, next) {
  const path = req.url.replace('/_v1_da/', '/');
 
  // Enforce allowlist before constructing upstream request
  if (!isPathAllowed(path, req.method, ALLOWED_PROXY_PATHS)) {
    res.statusCode = 404;
    res.statusMessage = 'Not Found';
    res.send({ error: 'Not Found' });
    return;
  }
 
  const reqUrl = `${process.env.DANSWER_URL || ''}/api${path}`;

The patch applies the same validation pattern to src/halloumi/middleware.js, restricting /_v1_ha/ proxy requests exclusively to POST /generate and POST /classify:

// Patched implementation in src/halloumi/middleware.js (2.0.4)
const ALLOWED_HALLOUMI_PATHS = [
  { path: '/generate', methods: ['POST'] },
  { path: '/classify', methods: ['POST'] },
];
 
export default async function middleware(req, res, next) {
  const path = req.url.replace('/_v1_ha/', '/');
 
  if (!isPathAllowed(path, req.method, ALLOWED_HALLOUMI_PATHS)) {
    res.statusCode = 404;
    res.statusMessage = 'Not Found';
    res.send({ error: 'Not Found' });
    return;
  }

Assessment of Fix Completeness

The fix effectively prevents arbitrary endpoint invocation by enforcing exact string matches (entry.path === cleanPath) or strict regular expression matches (/^\/persona\/\d+$/) after stripping query strings (strippedPath.split('?')[0]). Because cleanPath must match a static string or a digit-only suffix, URL-encoded path traversal sequences (such as /chat/send-message/../../admin) will fail the equality check and be rejected with an HTTP 404 response. However, note that req.url.replace('/_v1_da/', '/') only replaces the first occurrence of /_v1_da/, and the allowed conversational endpoints remain accessible to unauthenticated users by design so that anonymous website visitors can interact with the public chatbot.

Exploitation

Exploiting this vulnerability requires only network access to the HTTP/HTTPS port of the Volto server (typically port 3000 in development or 80/443 in production). No authentication credentials, session tokens, or prior knowledge of the internal network topology are needed. Because standard functionality of @eeacms/volto-chatbot requires configuring DANSWER_URL and DANSWER_API_KEY (or account credentials), any active deployment of the package is vulnerable in its default state.

To execute an attack, an adversary constructs an HTTP request targeting a privileged Danswer API route, prepends /_v1_da/ to the path, and transmits it to the Volto host. For example, to delete a user account on the upstream Danswer instance, the attacker issues an unauthenticated POST request to /_v1_da/admin/users/delete with a JSON body specifying the target user ID:

curl -i -X POST 'http://localhost:3000/_v1_da/admin/users/delete' \
  -H 'Content-Type: application/json' \
  --data '{"id":"victim-user-123"}'

When the Volto server receives this payload, it performs the following sequence of operations:

  1. Strips /_v1_da/ to yield /admin/users/delete.
  2. Prepends ${DANSWER_URL}/api to produce http://<danswer-internal-host>/api/admin/users/delete.
  3. Attaches Authorization: Bearer <DANSWER_API_KEY> to the outgoing headers.
  4. Forwards the POST method and JSON body {"id":"victim-user-123"} to the Danswer backend and returns the backend response directly to the caller.

> [!NOTE] > Beyond user deletion, an attacker can query /_v1_da/admin/connector/indexing-status to enumerate internal data sources, read sensitive indexed documents via search endpoints, modify LLM provider API keys stored in Danswer, or abuse the /_v1_ha/ endpoint to consume LLM quota via LLMGW_TOKEN.

Impact Assessment

The vulnerability carries a CVSS v3.1 base score of 8.2 (High) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N. The attack vector is Network (AV:N), attack complexity is Low (AC:L), no privileges (PR:N) or user interaction (UI:N) are required.

The primary impact falls on Confidentiality (C:H). Danswer/Onyx deployments typically index an organization's internal knowledge base, documents, wikis, and enterprise connectors. By querying administrative and search APIs through the proxy using the server's credentials, an attacker can exfiltrate restricted organizational documents, user lists, chat session logs, and potentially third-party LLM API keys or connector credentials stored within the Danswer backend.

The Integrity impact is rated Low (I:L) to High depending on the privileges assigned to the configured DANSWER_API_KEY. If the Volto proxy is configured with an administrative key—which is common in service-to-service integrations—the attacker can modify system personas, alter document sets, delete user accounts, or poison the knowledge base.

For organizations utilizing the Halloumi integration (/_v1_ha/), attackers can invoke unauthorized endpoints on the LLM Gateway (LLMGW_URL), leading to quota exhaustion, unauthorized model inference, and potential access to internal gateway management endpoints.

Remediation

Organizations running @eeacms/volto-chatbot must upgrade to version 2.0.4 or later. Version 2.0.4 incorporates commit a459b36dbd2c67e6397cc81910e27b9d611cca18, which restricts proxied requests to a strict allowlist of public conversational endpoints and returns HTTP 404 Not Found for all other paths or HTTP methods.

# Upgrade using Yarn
yarn upgrade @eeacms/volto-chatbot@^2.0.4
 
# Or upgrade using npm
npm update @eeacms/volto-chatbot

In addition to patching the package, administrators should enforce the principle of least privilege on the upstream Danswer and Halloumi credentials configured in the Volto environment. The account associated with DANSWER_API_KEY or DANSWER_USERNAME must be restricted to basic user permissions required for creating chat sessions and querying public personas, rather than holding global admin privileges.

If an immediate application upgrade is not feasible, security teams can mitigate the vulnerability at the network perimeter by configuring reverse proxies (such as Nginx, HAProxy, or Cloudflare) to drop requests targeting /_v1_da/ and /_v1_ha/ that do not match the required chat endpoints:

# Nginx mitigation block for @eeacms/volto-chatbot <= 2.0.3
location ~ ^/_v1_da/(?!persona|chat/(create-chat-session|send-message|create-chat-message-feedback)) {
    return 404;
}
 
location ~ ^/_v1_ha/(?!generate|classify) {
    return 404;
}

Official Patches

eeaPatch commit introducing proxy path and method allowlists
eeaRelease 2.0.4 tag

Fix Analysis (2)

Technical Appendix

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

Affected Systems

@eeacms/volto-chatbotPlone Volto deployments using @eeacms/volto-chatbot

Affected Versions Detail

Product
Affected Versions
Fixed Version
@eeacms/volto-chatbot
eea
<= 2.0.32.0.4
AttributeDetail
Advisory IDGHSA-w9x9-j56r-h98r
Weakness ClassCWE-862 (Missing Authorization / Confused Deputy)
CVSS v3.1 Score8.2 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N)
Attack VectorNetwork (Unauthenticated HTTP requests to /_v1_da/** or /_v1_ha/**)
Affected Package@eeacms/volto-chatbot (<= 2.0.3)
Patched Version2.0.4
Exploit StatusPublic Proof-of-Concept Available
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1078Valid Accounts
Initial Access
T1548Abuse Elevation Control Mechanism
Privilege Escalation
CWE-862
Missing Authorization

The software does not perform an authorization check when an actor attempts to access a resource or perform an action.

Known Exploits & Detection

GitHub Security AdvisoryOfficial advisory containing both cURL reproduction commands and a complete Python proof-of-concept script (poc.py).

Vulnerability Timeline

Fix commit a459b36dbd2c67e6397cc81910e27b9d611cca18 committed to eea/volto-chatbot
2026-06-21
Patched version 2.0.4 released
2026-06-21
GitHub Security Advisory GHSA-w9x9-j56r-h98r published (credited to EQSTLab)
2026-10-29

References & Sources

  • [1]GitHub Advisory Database: GHSA-w9x9-j56r-h98r
  • [2]Repository Security Advisory: GHSA-w9x9-j56r-h98r
  • [3]Vendor Fix Commit a459b36dbd2c67e6397cc81910e27b9d611cca18
  • [4]Release Tag 2.0.4
  • [5]Release 2.0.4 Changelog Commit
  • [6]GitHub Repository: eea/volto-chatbot

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 1 hour ago•GHSA-C33X-VCV4-VG3G
2.1

GHSA-c33x-vcv4-vg3g: Missing Slot Identifier Validation in Cedar Policy Language JSON Template Parser Causes Panic and Authorization Divergence

An improper input validation vulnerability (CWE-20) exists in the Entity Syntax Tree (EST) JSON deserialization component of the Cedar Policy Language (`cedar-policy` and `@cedar-policy/cedar-wasm`). When parsing JSON-formatted policy templates that define `is ... in` scope constraints on `principal` or `resource`, the parser used wildcard pattern matching that ignored the provided slot identifier (`?principal` or `?resource`). This omission allows malformed JSON templates to bypass initial deserialization validation, resulting in either a runtime panic during template linking or inverted slot bindings that alter authorization outcomes.

Amit Schendel
Amit Schendel
4 views•10 min read
•about 4 hours ago•CVE-2026-9705
6.5

CVE-2026-9705: Registration Access Token Authorization Bypass in Keycloak Dynamic Client Registration

CVE-2026-9705 is an insufficient session expiration and authorization bypass vulnerability in Keycloak and Red Hat build of Keycloak. The vulnerability occurs in the OAuth 2.0 Dynamic Client Registration Management Protocol implementation, where the authentication handler fails to verify whether a target client is enabled before accepting requests authenticated with a previously issued Registration Access Token (RAT). Consequently, an actor possessing a valid RAT for an administratively disabled client can query, update, and re-enable the client configuration, restoring revoked access to realm resources.

Amit Schendel
Amit Schendel
5 views•10 min read
•about 5 hours ago•CVE-2026-9800
8.1

CVE-2026-9800: Authorization Bypass in Keycloak Policy Enforcer via Unnormalized URI Substring Matching

CVE-2026-9800 is an authorization bypass vulnerability affecting the Keycloak Policy Enforcer (org.keycloak:keycloak-policy-enforcer), which is integrated into Red Hat build of Keycloak, Red Hat build of Quarkus, Red Hat Single Sign-On 7, and Red Hat JBoss Enterprise Application Platform Expansion Pack. The flaw stems from improper comparison logic in the PolicyEnforcer.isDefaultAccessDeniedUri method, which uses loose substring matching on the full raw request URI rather than exact, normalized path comparisons against the configured access-denied landing page. Consequently, an authenticated attacker possessing any valid low-privileged token can bypass role-based, scope-based, and User-Managed Access (UMA) policy evaluations by embedding the access-denied path segment into the URL path or query parameters.

Amit Schendel
Amit Schendel
5 views•8 min read
•about 6 hours ago•CVE-2026-9799
4.6

CVE-2026-9799: Authorization Bypass via UMA Permission Ticket Wildcard in Keycloak

CVE-2026-9799 is an authorization bypass vulnerability in the User-Managed Access (UMA) subsystem of Keycloak (org.keycloak.authorization). When a resource server is configured with the non-default PERMISSIVE policy enforcement mode, an authenticated user holding a valid UMA permission ticket for a single typed resource can obtain an authorization Requesting Party Token (RPT) granting access to all resources of the same type across the resource server. By submitting an authorization request with the type selector prefix 'resource-type-any:<type>', the attacker bypasses instance-level owner approval checks for unshared peer resources that lack explicit static administrative policies.

Alon Barad
Alon Barad
4 views•9 min read
•about 7 hours ago•CVE-2026-9083
4.9

CVE-2026-9083: Arbitrary Filesystem Path Probing in Keycloak Java Keystore Key Provider

CVE-2026-9083 is a path traversal and information disclosure vulnerability (CWE-22) affecting Keycloak and the Red Hat build of Keycloak. The vulnerability resides in the Java Keystore key provider component (JavaKeystoreKeyProviderFactory), which fails to restrict the user-supplied keystore file path to a designated directory. An authenticated realm administrator holding the 'manage-realm' role can supply arbitrary absolute or relative filesystem paths when configuring a key provider. Because the application returns distinct error messages depending on whether the target path does not exist, lacks read permissions, or fails keystore parsing, an attacker can use this component as an oracle to probe the underlying host filesystem.

Alon Barad
Alon Barad
5 views•11 min read
•about 8 hours ago•CVE-2026-9086
7.3

CVE-2026-9086: Stored Cross-Site Scripting via Case-Sensitive URI Scheme Validation Bypass in Keycloak

CVE-2026-9086 is a stored Cross-Site Scripting (XSS) vulnerability in Keycloak and the Red Hat build of Keycloak. The vulnerability stems from a case-sensitive URI scheme validation check in DefaultClientValidationProvider, allowing attackers with client registration or management permissions to inject javascript: or data: URIs using mixed-case characters.

Amit Schendel
Amit Schendel
5 views•10 min read