CVE-2026-123811
Dynatrace MCP Server: Unauthenticated HTTP MCP Tool Invocation in `@dynatrace-oss/dynatrace-mcp-server`
Dynatrace MCP Server is an MCP server for Dynatrace Observability. Prior to 2.0.0, a server started with the --http option accepts JSON-RPC tools/call requests without authentication, session validation, or Host and Origin protections before dispatching them under the server's configured Dynatrace credentials. A network-reachable caller can invoke execute_dql to read logs, security events, user sessions, and other Grail data, or invoke create_dynatrace_notebook to create tenant-visible notebooks. The send_event path is not affected because its requestHumanApproval gate blocks this attack path, and reset_grail_budget only demonstrates dispatch without accessing Dynatrace data. This issue is fixed in version 2.0.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- High
- Integrity
- Low
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
7.5
Dynatrace MCP Server: Unauthenticated HTTP MCP Tool Invocation in `@dynatrace-oss/dynatrace-mcp-server`
Dynatrace MCP Server is an MCP server for Dynatrace Observability. Prior to 2.0.0, a server started with the --http option accepts JSON-RPC tools/call requests without authentication, session validation, or Host and Origin protections before dispatching them under the server's configured Dynatrace credentials. A network-reachable caller can invoke execute_dql to read logs, security events, user sessions, and other Grail data, or invoke create_dynatrace_notebook to create tenant-visible notebooks. The send_event path is not affected because its requestHumanApproval gate blocks this attack path, and reset_grail_budget only demonstrates dispatch without accessing Dynatrace data. This issue is fixed in version 2.0.0.
- Record
CVE-2026-123811- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L - Weakness
- CWE-306
- Updated
- 2026-11-09
EUVDEUVD-2026-120446
7.5
Dynatrace MCP Server is an MCP server for Dynatrace Observability. Prior to 2.0.0, a server started with the --http option accepts JSON-RPC tools/call requests without authentication, session validation, or Host and Origin protections before dispatching them under the server's configured Dynatrace credentials. A network-reachable caller can invoke execute_dql to read logs, security events, user sessions, and other Grail data, or invoke create_dynatrace_notebook to create tenant-visible notebooks. The send_event path is not affected because its requestHumanApproval gate blocks this attack path, and reset_grail_budget only demonstrates dispatch without accessing Dynatrace data. This issue is fixed in version 2.0.0.
- Record
EUVD-2026-120446- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L - Updated
- 2026-11-09
GitHub AdvisoriesGHSA-p7w7-4929-vpj5
7.5
`@dynatrace-oss/dynatrace-mcp-server` has Unauthenticated HTTP MCP Tool Invocation
Summary
@dynatrace-oss/dynatrace-mcp-server v1.8.5 exposes an HTTP transport mode (--http flag) that performs no authentication, session validation, or origin/host verification before dispatching MCP tool calls. Any network-reachable attacker can send a raw JSON-RPC tools/call request without an Authorization header and have it executed directly under the victim server's Dynatrace credentials. Confirmed high-impact tools reachable without authentication include execute_dql (reads arbitrary Grail data, including logs, security events, and user sessions) and create_dynatrace_notebook (writes notebooks to the tenant).
Details
When the server is started with the --http flag, an HTTP server is created at src/index.ts:1621. For every inbound request the handler creates a new StreamableHTTPServerTransport instance:
// src/index.ts:1638-1640
const httpTransport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // No Session ID needed
});
No bearer-token check, session token, Host allowlist, or Origin allowlist is configured on either the transport or in the surrounding request handler. The raw body is parsed and handed directly to the transport:
// src/index.ts:1648-1668
body = JSON.parse(rawBody);
...
await httpTransport.handleRequest(req, res, body);
Two tools are directly reachable by an unauthenticated HTTP caller without any requestHumanApproval gate:
execute_dql — Confidentiality: High
// src/index.ts:746-769
// No requestHumanApproval before createAuthenticatedHttpClient
const dtClient = await createAuthenticatedHttpClient(scopesBase.concat('storage:buckets:read', ...));
return executeDql(dtClient, { query });
An attacker can run arbitrary DQL queries (logs, security events, user sessions, metrics) using the victim's Dynatrace credentials.
create_dynatrace_notebook — Integrity: Low
// src/index.ts:1593-1600
// No requestHumanApproval before createAuthenticatedHttpClient
const dtClient = await createAuthenticatedHttpClient(scopesBase.concat('document:write'));
return createNotebook(dtClient, { name, sections });
An attacker can create notebooks under the victim's tenant.
Note on
send_event: The initial static report claimedsend_eventwas also unguarded. Code inspection atsrc/index.ts:1367confirms arequestHumanApprovalcall exists inside thesend_eventhandler. An HTTP attacker (no MCP elicitation loop) causes that call to throw, and the catch block returnsfalse, effectively blocking the write. Thesend_eventpath is therefore not exploitable via the HTTP attack vector.
Note on PoC tool
reset_grail_budget: The PoC usesreset_grail_budget(src/index.ts:1218-1239), which performs no Dynatrace API calls — it resets in-memory budget counters only. It is used purely as a safe, self-contained proof that unauthenticated dispatch works; actual data exfiltration requiresexecute_dqlwith real credentials.
PoC
Environment setup (Docker):
# Build from repository root
docker build \
-t dynatrace-mcp-vuln001:latest \
-f /path/to/vuln-001/Dockerfile \
/path/to/dynatrace-mcp/repo
# Run — abc12345 in hostname activates demo mode, skipping real API connectivity check
docker run -d \
--name dynatrace-mcp-vuln001-test \
-p 127.0.0.1:3999:3999 \
-e DT_ENVIRONMENT=https://abc12345.apps.dynatrace.com \
-e DT_PLATFORM_TOKEN=fake-token-for-poc \
dynatrace-mcp-vuln001:latest \
--http --port 3999 --host 0.0.0.0
Unauthenticated tool invocation (no Authorization header):
curl -sS -N -X POST http://127.0.0.1:3999/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'Mcp-Protocol-Version: 2025-03-26' \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"reset_grail_budget","arguments":{}}}'
Observed response (HTTP 200, no authentication required):
HTTP/1.1…
- Record
GHSA-p7w7-4929-vpj5- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L - Weakness
- CWE-306
- Updated
- 2026-11-09
NVD
7.5
Dynatrace MCP Server is an MCP server for Dynatrace Observability. Prior to 2.0.0, a server started with the --http option accepts JSON-RPC tools/call requests without authentication, session validation, or Host and Origin protections before dispatching them under the server's configured Dynatrace credentials. A network-reachable caller can invoke execute_dql to read logs, security events, user sessions, and other Grail data, or invoke create_dynatrace_notebook to create tenant-visible notebooks. The send_event path is not affected because its requestHumanApproval gate blocks this attack path, and reset_grail_budget only demonstrates dispatch without accessing Dynatrace data. This issue is fixed in version 2.0.0.
- Record
CVE-2026-123811- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L - Weakness
- CWE-306
- Updated
- 2026-11-09
OSV
7.5
Dynatrace MCP Server: Unauthenticated HTTP MCP Tool Invocation in `@dynatrace-oss/dynatrace-mcp-server`
Dynatrace MCP Server is an MCP server for Dynatrace Observability. Prior to 2.0.0, a server started with the --http option accepts JSON-RPC tools/call requests without authentication, session validation, or Host and Origin protections before dispatching them under the server's configured Dynatrace credentials. A network-reachable caller can invoke execute_dql to read logs, security events, user sessions, and other Grail data, or invoke create_dynatrace_notebook to create tenant-visible notebooks. The send_event path is not affected because its requestHumanApproval gate blocks this attack path, and reset_grail_budget only demonstrates dispatch without accessing Dynatrace data. This issue is fixed in version 2.0.0.
- Record
CVE-2026-123811- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L - Weakness
- CWE-306
- Updated
- 2026-11-10
OSVGHSA-p7w7-4929-vpj5
7.5
`@dynatrace-oss/dynatrace-mcp-server` has Unauthenticated HTTP MCP Tool Invocation
Summary
@dynatrace-oss/dynatrace-mcp-server v1.8.5 exposes an HTTP transport mode (--http flag) that performs no authentication, session validation, or origin/host verification before dispatching MCP tool calls. Any network-reachable attacker can send a raw JSON-RPC tools/call request without an Authorization header and have it executed directly under the victim server's Dynatrace credentials. Confirmed high-impact tools reachable without authentication include execute_dql (reads arbitrary Grail data, including logs, security events, and user sessions) and create_dynatrace_notebook (writes notebooks to the tenant).
Details
When the server is started with the --http flag, an HTTP server is created at src/index.ts:1621. For every inbound request the handler creates a new StreamableHTTPServerTransport instance:
// src/index.ts:1638-1640
const httpTransport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // No Session ID needed
});
No bearer-token check, session token, Host allowlist, or Origin allowlist is configured on either the transport or in the surrounding request handler. The raw body is parsed and handed directly to the transport:
// src/index.ts:1648-1668
body = JSON.parse(rawBody);
...
await httpTransport.handleRequest(req, res, body);
Two tools are directly reachable by an unauthenticated HTTP caller without any requestHumanApproval gate:
execute_dql — Confidentiality: High
// src/index.ts:746-769
// No requestHumanApproval before createAuthenticatedHttpClient
const dtClient = await createAuthenticatedHttpClient(scopesBase.concat('storage:buckets:read', ...));
return executeDql(dtClient, { query });
An attacker can run arbitrary DQL queries (logs, security events, user sessions, metrics) using the victim's Dynatrace credentials.
create_dynatrace_notebook — Integrity: Low
// src/index.ts:1593-1600
// No requestHumanApproval before createAuthenticatedHttpClient
const dtClient = await createAuthenticatedHttpClient(scopesBase.concat('document:write'));
return createNotebook(dtClient, { name, sections });
An attacker can create notebooks under the victim's tenant.
Note on
send_event: The initial static report claimedsend_eventwas also unguarded. Code inspection atsrc/index.ts:1367confirms arequestHumanApprovalcall exists inside thesend_eventhandler. An HTTP attacker (no MCP elicitation loop) causes that call to throw, and the catch block returnsfalse, effectively blocking the write. Thesend_eventpath is therefore not exploitable via the HTTP attack vector.
Note on PoC tool
reset_grail_budget: The PoC usesreset_grail_budget(src/index.ts:1218-1239), which performs no Dynatrace API calls — it resets in-memory budget counters only. It is used purely as a safe, self-contained proof that unauthenticated dispatch works; actual data exfiltration requiresexecute_dqlwith real credentials.
PoC
Environment setup (Docker):
# Build from repository root
docker build \
-t dynatrace-mcp-vuln001:latest \
-f /path/to/vuln-001/Dockerfile \
/path/to/dynatrace-mcp/repo
# Run — abc12345 in hostname activates demo mode, skipping real API connectivity check
docker run -d \
--name dynatrace-mcp-vuln001-test \
-p 127.0.0.1:3999:3999 \
-e DT_ENVIRONMENT=https://abc12345.apps.dynatrace.com \
-e DT_PLATFORM_TOKEN=fake-token-for-poc \
dynatrace-mcp-vuln001:latest \
--http --port 3999 --host 0.0.0.0
Unauthenticated tool invocation (no Authorization header):
curl -sS -N -X POST http://127.0.0.1:3999/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'Mcp-Protocol-Version: 2025-03-26' \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"reset_grail_budget","arguments":{}}}'
Observed response (HTTP 200, no authentication required):
HTTP/1.1…
- Record
GHSA-p7w7-4929-vpj5- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:L - Weakness
- CWE-306
- Updated
- 2026-11-09
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@dynatrace-oss/dynatrace-mcp-servernpm |
through 1.8.7 | 2.0.0 |
@dynatrace-oss/dynatrace-mcp-servernpm |
before 2.0.0 | 2.0.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| references | NVD, OSV | |
| description, references, severity, title | CVE List | |
| aliases, products, references | EUVD, OSV | |
| aliases, facts, id | GitHub Advisories | |
| first indexed | GitHub Advisories, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-123811 is a high vulnerability (CVSS 7.5) in Dynatrace-oss Dynatrace-mcp, published July 31, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.24%, the 15th percentile. Fixed in @dynatrace-oss/dynatrace-mcp-server 2.0.0.
References
github.com/dynatrace-oss/dynatrace-mcp/security/advisories/GHSA-p7w7-4929-vpj5
github.com/dynatrace-oss/dynatrace-mcp/commit/8f12972481e9165e8bd24d63b0a9e71976f85a43
github.com/dynatrace-oss/dynatrace-mcp/commit/ac5251edfcf9511c6c662414da743383e7d1451c
github.com/dynatrace-oss/dynatrace-mcp/commit/ead820322238633f5b289778c57faf5d3a8d73f9
github.com/dynatrace-oss/dynatrace-mcp/releases/tag/v2.0.0
github.com/dynatrace-oss/dynatrace-mcp/pull/536
Left out here: the rest of 2 source descriptions. The JSON record has them.