Skip to main content

@dynatrace-oss/dynatrace-mcp-server has a workflow template injection via create_workflow_for_notification

0
Medium
Published: 07/31/2026 (07/31/2026, 16:01:07 UTC)
Source: GCVE Database
Product: @dynatrace-oss/dynatrace-mcp-server

Description

### Summary A template injection vulnerability in the `create_workflow_for_notification` tool lets a caller embed Jinja2 expressions that the Dynatrace workflow engine evaluates at runtime, exfiltrating event data to attacker-controlled destinations through a workflow that persists in the tenant after the MCP session ends. ### Details The `create_workflow_for_notification` tool interpolates three caller-supplied parameters (`teamName`, `problemType`, `channel`) directly into a Dynatrace Workflow definition. Dynatrace Workflows use Jinja2 templating: per the [official documentation](https://docs.dynatrace.com/docs/analyze-explore-automate/workflows/reference), `{{ ... }}` expressions in action inputs are evaluated at workflow runtime for every action except `Run Javascript` (which is carved out specifically to avoid code injection). A caller can therefore supply, for example, `teamName = "{{ event() }}"` and have the workflow engine evaluate that expression at runtime, serialising the full event object into the message body delivered to the Slack channel. The vulnerable code is in `src/capabilities/create-workflow-for-problem-notification.ts`, lines 82-99: ```typescript let notificationWorkflow: WorkflowCreate = { title: `[MCP POC] Notify team ${teamName} on problem of type ${problemType}`, description: `Automatically created workflow to notify team ${teamName} on problems of type ${problemType} - ...`, isPrivate: isPrivate, type: 'SIMPLE', tasks: { send_notification: { name: 'Send notification', action: 'dynatrace.slack:slack-send-message', description: 'Sends a notification to a Slack channel', input: { connectionId: 'slack-connection-id', channel: `{{ \"${channel}\" }}`, // <-- channel sits inside {{ }} message: `🚨 Alert for Team ${teamName}\n*Problem Type*: ${problemType}\n` + `*Problem ID*: {{ event()["display_id"] }}\n*Status*: {{ event()["event.status"] }}\n` + `<{{ environment().url }}/ui/apps/.../problem/{{ event()["event.id"] }}|Click here>`, }, active: true, }, }, }; ``` The action used is `dynatrace.slack:slack-send-message`, which is not in the documented Jinja-expression exception list. Its inputs are evaluated at workflow runtime. The schema in `src/index.ts:1052-1070` registers `teamName`, `problemType`, and `channel` as `z.string().optional()` with no pattern validation. The `isPrivate` parameter has `.default(false)`, so created workflows are visible tenant-wide unless the caller explicitly sets it. The approval prompt at `src/index.ts:1069-1072`: ```typescript const approved = await requestHumanApproval( `Create a workflow for notifying team ${teamName} via ${channel} about ${problemType} problems`, ); ``` Renders `{{ event() }}` literally to the operator with no indication that it will be templated, and does not surface the workflow's visibility. The workflow is persistent: it remains in the tenant after the MCP session ends, after the operator's MCP credentials are revoked, and after the MCP server is uninstalled. It fires on every matching problem until manually deleted from the Workflows app. The `channel` parameter is uniquely dangerous because it is interpolated inside an existing `{{ "..." }}` expression context - close the string with `"` and you can run arbitrary Jinja expressions in the destination field itself. ### PoC Tested end-to-end against a real Dynatrace tenant. The MCP server was run in stdio mode with the operator's Platform Token. A `tools/call create_workflow_for_notification` was sent with: ```json { "teamName": "{{ event() }}", "problemType": "ERROR", "channel": "#mcp-sec-poc", "isPrivate": true } ``` The operator approved the prompt (which read: `"Create a workflow for notifying team {{ event() }} via #mcp-sec-poc about ERROR problems"`). The MCP returned a workflow ID. Fetching the stored workflow body via the Dynatrace Automation API (`GET /platform/automation/v1/workflows/<id>`) showed the injected expression stored verbatim: ``` title: "[MCP POC] Notify team {{ event() }} on problem of type ERROR" message: "🚨 Alert for Team {{ event() }}\n*Problem Type*: ERROR\n*Problem ID*: {{ event()[\"display_id\"] }}\n..." channel: '{{ "#mcp-sec-poc" }}' action: "dynatrace.slack:slack-send-message" ``` The workflow was then triggered manually via the "Run workflow" feature in the Dynatrace Workflows app, with a synthetic event payload `{"display_id":"P-123","event.status":"OPEN","event.id":"abc-123"}`. The execution log for the `send_notification` task shows the workflow engine evaluated the injected expressions at runtime. The "Input" tab for the executed action contains: ``` channel: #mcp-sec-poc message: Alert for Team {'display_id': 'P-123', 'event.status': 'OPEN', 'event.id': 'abc-123'} *Problem Type*: ERROR *Problem ID*: P-123 *Status*: OPEN <ht

CVSS v3.1

Score 4.2medium

Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
Required
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
None
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

Affected software

npmghsa
@dynatrace-oss/dynatrace-mcp-server
Affected versions
<2.0.0

Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.

AI-Powered Analysis

Machine-generated threat intelligence

AILast updated: 07/31/2026, 20:19:50 UTC

Technical Analysis

The vulnerability arises from the create_workflow_for_notification tool interpolating three caller-supplied parameters (teamName, problemType, channel) directly into a Dynatrace Workflow definition that uses Jinja2 templating. Since the workflow engine evaluates expressions in action inputs at runtime, an attacker can supply malicious Jinja2 expressions that are executed when the workflow runs. The channel parameter is especially dangerous because it is interpolated inside an existing Jinja2 expression context, enabling arbitrary Jinja2 code execution. The workflow created remains persistent in the tenant after the MCP session ends and fires on matching problems until manually deleted. The approval prompt does not clearly indicate the templating risk or workflow visibility, increasing the chance of inadvertent approval. This vulnerability is tracked as CWE-1336 and has a CVSS 3.1 score of 4.2 (medium severity).

Potential Impact

An attacker with the ability to call create_workflow_for_notification can inject Jinja2 template expressions that the Dynatrace workflow engine evaluates at runtime. This can lead to exfiltration of event data to attacker-controlled destinations via persistent workflows that remain active in the tenant beyond the MCP session. The injected workflows can leak sensitive event information and potentially manipulate notification channels. The vulnerability requires user interaction (approval prompt) and has a high attack complexity, limiting immediate exploitation but posing a persistent risk if exploited.

Mitigation Recommendations

A patch is available for this vulnerability; users should upgrade to version 2.0.0 or later of @dynatrace-oss/dynatrace-mcp-server. Until patched, operators should carefully review workflow creation prompts for suspicious template expressions and avoid approving workflows with untrusted input. Manually review and delete any suspicious workflows created via this tool. Follow the vendor advisory for official remediation guidance.

Pro Console: star threats, build custom feeds, automate alerts via Slack, email & webhooks.Upgrade to Pro

Technical Details

Gcve Source
db.gcve.eu
Osv Id
GHSA-xrmj-5g4g-8987
Osv Schema Version
1.4.0
Ecosystems
["npm"]
Database Specific Severity
MODERATE
Cvss Version
3.1

Threat ID: 6a6cf7f5bf32cb7a342b439d

Added to database: 07/31/2026, 19:31:01 UTC

Last enriched: 07/31/2026, 20:19:50 UTC

Last updated: 09/10/2026, 01:03:12 UTC

Views: 39

Community Reviews

0 reviews

Crowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.

Sort by
Loading community insights…

Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.

Actions

PRO

Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.

Please log in to the Console to use AI analysis features.

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

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses