Back to skill

Security audit

Dify Workflow DSL Expert

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Dify workflow DSL helper; its main risk is that some example workflows can send data to configured external APIs or LLM providers if a user imports and runs them.

Installers should treat the bundled workflows as examples, not production-ready automations. Before importing any template, verify model providers, external URLs, API key usage, and whether fetched or user-supplied content will be sent to an LLM; prefer redaction, trusted endpoints, and scoped test credentials.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
templates/http-llm-workflow.yaml:123
Finding

Untrusted Remote API Content Is Passed Directly to an LLM

Content
View full analysis

Vulnerability Details

File Location: templates/http-llm-workflow.yaml, lines 123-125 and 154-177, with the unsafe prompt interpolation at lines 257-274
Vulnerability Type: Indirect prompt injection through untrusted remote content
Risk Level: Medium

Vulnerable Code

yaml
url: https://api.example.com/resource
params: "id:{{#1700000000001.resource_id#}}"
headers: "Authorization:Bearer {{#env.API_KEY#}}"
yaml
code: |
  import json

  def main(response_body, status_code):
      """Parse API response and extract data."""
      result = {
          "success": False,
          "content": "",
          "error_message": ""
      }

      # Check status code
      if status_code != 200:
          result["error_message"] = f"API returned status {status_code}"
          return result

      # Parse JSON
      if not response_body:
          result["error_message"] = "Empty response"
          return result

      try:
          data = json.loads(response_body)
          if data.get("success"):
              result["success"] = True
              result["content"] = data.get("content", "")
          else:
              result["error_message"] = data.get("message", "Unknown error")
      except json.JSONDecodeError as e:
          result["error_message"] = f"JSON parse error: {str(e)}"

      return result
yaml
prompt_template:
  - id: system-prompt
    role: system
    text: |
      You are an expert content analyst.
      Analyze the provided content and provide insights.
  - id: user-prompt
    role: user
    text: |
      Please analyze the following content:

      {{#1700000000003.content#}}

      Provide:
      1. Summary (2-3 sentences)
      2. Key points (bullet list)
      3. Quality score (1-10)

Technical Analysis

The workflow retrieves content from an external API, extracts the response's content f ...[truncated 2666 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat every external response as untrusted input, even when it comes from an authenticated API.
  2. Add an explicit system-level rule stating that retrieved content is data only and that any instructions, requests, or policy text inside it must not be followed.
  3. Place the remote content inside clear delimiters such as XML-style data tags and describe those delimiters in the system prompt.
  4. Validate the response schema and impose a conservative maximum length before sending content to the model.
  5. Apply allowlist-based validation where the expected content format permits it; reject unexpected fields or content types.
  6. Keep the analysis LLM isolated from tools that can execute commands, access secrets, modify workflows, send messages, or perform privileged network operations.
  7. If the output drives automated actions, validate it against a strict structured-output schema and require independent policy checks or human approval.
  8. Require users to replace and verify api.example.com before import. Document that the configured endpoint receives both the API credential and resource identifier.
  9. Restrict outbound HTTP access to approved hosts and HTTPS destinations at the Dify deployment or network layer.
  10. Use a narrowly scoped API key with only the permissions required to read the intended resource, and rotate it if it is ever sent to an untrusted destination.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description presents a broad workflow-authoring and validation tool for Dify DSL, but the actual code only generates timestamp-based node IDs. While such IDs might support workflow editing indirectly, this script does not create, edit, debug, validate, import, export, or otherwise operate on Dify workflow DSL. The primary purpose is materially narrower and different from the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 133)May include surrounding context.

md
- [`references/node_types.md`](references/node_types.md): Node-Typen und Einsatzzwecke

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file defines a generic conversational workflow that routes end-user prompts to LLMs, rather than a workflow for creating, editing, debugging, or validating Dify workflow DSL as the skill metadata claims. This capability mismatch is dangerous because a user or downstream agent may invoke the skill expecting constrained DSL-manipulation behavior but instead send arbitrary prompts to a general/code assistant, expanding scope and increasing the risk of misuse, prompt injection exposure, or unintended actions in larger agent pipelines.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document content is written entirely in German and does not indicate that language is optional or limited to a specific justified region or audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The markdown instructions alternate between German and English across core sections, including operating principles and response patterns. This imposes a language expectation on users without explicit opt-in or justification, which matches the language/locale policy violation criterion.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The routing condition classifies any query containing the substring 'code' as a coding request, which is an imprecise trigger that can easily match unrelated text and send users to the wrong branch. In this skill context, weak routing makes the behavior less predictable and undermines any assumption that the workflow is performing reliable DSL-focused handling, potentially causing incorrect outputs or bypass of intended task boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The workflow sends the full original user input and internal error details directly to an external LLM during the fail-branch path. If the input contains secrets, personal data, or proprietary content, a malformed JSON error will cause that sensitive data to be disclosed to the model provider without explicit user notice or minimization. The skill context makes this more dangerous because error paths are easy to overlook, yet they may still process arbitrary user-supplied data from self-hosted Dify instances.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The workflow forwards raw user input directly to Anthropic's external LLM service via the user prompt template, with no disclosure, consent, redaction, or guardrails. In a self-hosted Dify context, users may reasonably assume data stays local, so this can cause unintended transmission of sensitive or regulated information to a third party.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document’s natural-language instructions and guidance are entirely in German, which can impose a specific language on users without any opt-in or justification. The policy allows locale constraints only when user choice is offered or the restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation explicitly suggests including secrets during export and labels it only as a generic 'security risk,' without a strong prohibition, examples of exposure paths, or safer defaults. In a workflow-editing skill for self-hosted Dify, this can normalize unsafe handling of API keys and credentials, increasing the chance that users export, store, share, or version-control sensitive secrets.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document is primarily written in English, but these sections abruptly require German ('Answer ist kein Workflow-Ende', 'Trigger nicht fuer Chatflow zusagen', etc.) with no user opt-in or justification. This is a natural-language policy violation because it forces a specific language for part of the skill content without offering a choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown reference uses German throughout, which effectively forces a specific language on users. The file does not provide an opt-in, alternative language, or justification that the skill is intentionally region- or locale-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file includes an HTTP Request Node template that sends workflow data to an external API and references an environment API key in the Authorization header. The surrounding description explains configuration details but does not warn that using this node can transmit user or system data off-platform or involve credentials.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/node-templates.md (reported line 310)May include surrounding context.

md
# Request Configuration
    method: post                             # get | post | put | delete | patch
    url: https://api.example.com/endpoint

    # Query Parameters (key:value format)
    params: "id:{{#1700000000001.resource_id#}}&format:json"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/node_types.md (reported line 395)May include surrounding context.

md
# Request Configuration
    method: post                             # get | post | put | delete | patch
    url: https://api.example.com/endpoint

    # Query Parameters (key:value format)
    params: "id:{{#1700000000001.resource_id#}}&format:json"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The template defines a secret environment variable for third-party API authentication even though the skill is described as workflow editing/validation support, not external API integration. Including secret handling encourages users to inject credentials into a template that may later transmit data externally, expanding the blast radius if misused or misunderstood.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The workflow contains explicit external transmission to a remote API endpoint, which is security-relevant because it moves user-supplied identifiers and authorization-bearing requests off-platform. In a skill whose declared role is editing/validating Dify DSL, this is more dangerous because users may not expect imported examples to perform live network access.

Content

Scanner excerpt · templates/http-llm-workflow.yaml (reported line 123)May include surrounding context.

yaml
title: Fetch Data
          desc: Call external API
          method: get
          url: https://api.example.com/resource
          params: "id:{{#1700000000001.resource_id#}}"
          headers: "Authorization:Bearer {{#env.API_KEY#}}"
          body:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This template embeds outbound HTTP request capability to an arbitrary third-party API, which is outside the stated skill purpose of editing or validating Dify workflow DSL. In this context, shipping a ready-made networked workflow increases the chance that users import a template that exfiltrates inputs or fetches untrusted data without realizing the security boundary has changed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Content fetched from an external API is passed directly into an LLM prompt without any disclosure, consent flow, or data-classification check. This creates a data-sharing risk because users may not realize third-party or sensitive content retrieved over HTTP will be transmitted onward to the model provider for analysis.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This reference file is primarily written in English, but L016 switches to German for a key explanatory sentence and several subsequent bullet sections also continue in German. That imposes a language choice on readers without opt-in or justification, which conflicts with the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file is written entirely in German, including instructional content, while embedded source links are English. Under the policy rule, forcing a specific language without opt-in can be a natural-language policy violation when no user choice or justification is provided.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This markdown file demonstrates inserting env.API_KEY directly into an HTTP Authorization header, which affects user privacy and secrets handling. While L192 notes that environment variables are for sensitive data, the guide does not warn users that values placed into requests may be transmitted to external services or exposed in debugging/logging contexts.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This manifest file uses broad labels like "Minimal workflow template" and "Minimal Workflow" without clarifying the intended invocation context, trigger conditions, or exclusions. In a skill catalog or automated routing context, such generic descriptions can make it unclear when this workflow should be selected versus other skills.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.