Back to skill

Security audit

dify-dsl-to-code

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Dify-to-code generator, but the generated verifier and service templates can execute untrusted workflow code and expose secrets or workflow execution without enough safeguards.

Review and harden generated projects before deployment. Do not run the verifier or generated service on untrusted DSLs outside a sandbox. Add authentication, rate limits, request size limits, code-node isolation, an allowlist for env/secret names, HTTP destination allowlists, and pinned dependencies before exposing the service or loading real credentials.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
references/codegen-patterns.md:78
Finding

Untrusted DSL Code Nodes Are Preserved Without Sandbox Controls

Content
View full analysis
dict` | | `variables[]` / `inputs` | 入参映射:`{variable: 形参名, value_selector: [...]}` | | `outputs` | 出参声明:`{key: {type, children}}` | 代码化铁律:**原样搬运,禁止重写逻辑**;javascript 代码需 Node 运行时或征得用户同意后改写。 ``` ### Technical Analysis The Skill treats a user-supplied Dify DSL as a source of executable Python or JavaScript and explicitly requires inline code to be copied without modifying its logic. Dify code nodes are expected to run under Dify's sandbox model, but the standalone FastAPI and Express templates do not provide an equivalent sandbox, capability boundary, filesystem restriction, network restriction, execution timeout, or resource quota. Consequently, preserving code verbatim does not preserve its original security context. A code node that was constrained inside Dify may receive the full privileges of the generated service process after conversion. The bundled example code nodes are benign text-processing routines, so this finding does not assert that the examples themselves are malicious. The vulnerability arises from the handling policy for arbitrary user-supplied DSL files. ### Attack Path 1. An attacker supplies or modifies a Dify DSL file. 2. The DSL contains a Python or JavaScript code node with a malicious `main` implementation. 3. The Skill follows its documented rule and copies the implementation into a generated handler without ...[truncated 950 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/verify_project.py:37
Finding

Project Verification Imports and Executes Generated Code

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/dsl-components.md:202
Finding

Generated HTTP Nodes Lack SSRF and Secret-Destination Controls

Content
View full analysis
Any: """Resolve a single reference body like 'node-1.text' or 'env.KEY'.""" ref = ref.strip() if ref.startswith(("env.", "secret.")): return os.environ.get(ref.split(".", 1)[1], "") if ref == "context": return self.get("__runtime__", "context", "") ``` The equivalent Node implementation is: ```javascript resolveRef(ref) { ref = ref.trim(); if (ref.startsWith('env.') || ref.startsWith('secret.')) { return process.env[ref.slice(ref.indexOf('.') + 1)] ?? ''; } } ``` ### Technical Analysis Outbound HTTP is necessary to reproduce a legitimate Dify `http-request` node. The security issue is that the generation guidance provides no destination restrictions or secret-flow policy. The instructions allow URL, headers, request body, and authorization configuration to be interpolated before sending the request. The variable resolvers permit ...[truncated 1830 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/templates/python-fastapi/app/main.py:35
Finding

Generated Workflow Execution Endpoints Have No Authentication or Authorization

Content
View full analysis
{ try { const engine = new Engine(DEFINITION, buildHandlers()); const outputs = await engine.run(req.body.inputs || {}); res.json({ outputs }); } catch (e) { const notImpl = String(e.message || '').includes('no handler registered'); res.status(notImpl ? 501 : 500).json({ detail: `${e.name}: ${e.message}` }); } }); app.post('/run/stream', async (req, res) => { res.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive', }); res.flushHeaders(); const engine = new Engine(DEFINITION, buildHandlers()); try { for await (const [event, payload] of engine.runStream(req.body.inputs || {})) { ...[truncated 2143 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
assets/templates/python-fastapi/requirements.txt:1
Finding

Unpinned Dependencies and Non-Reproducible Container Builds

Content
View full analysis
=0.110 uvicorn[standard]>=0.29 pydantic>=2.6 python-dotenv>=1.0 httpx>=0.27 jinja2>=3.1 ``` Node dependencies: ```json "dependencies": { "dotenv": "^16.4.5", "express": "^4.19.2" } ``` Node container installation: ```dockerfile WORKDIR /srv COPY package.json ./ RUN npm install --omit=dev COPY src ./src ``` ### Technical Analysis The Python manifest uses open-ended minimum-version constraints. The Node manifest uses caret ranges, has no bundled lockfile, and the Dockerfile runs `npm install` rather than a frozen installation command. As a result, identical source code can resolve different dependency and transitive-dependency versions at different times. Future package releases can therefore enter production images without a corresponding change to the Skill or generated project. The audit did not identify a specific typosquatted package or confirmed malicious dependency. This finding concerns the absence of reproducible dependency controls and the resulting supply-chain exposure. ### Attack Path 1. A new package or transitive-dependency version is published within an accepted version range. 2. A user generates or rebuilds a project from the template. 3. `pip` or `npm install` resolves the newly available version. 4. The package's installation or runtime code becomes part of the service. 5. If the release is compromised or malicious, its code executes during installation or when imported by the application. ### Impact Assessment A compromised dependency may execute with build-time or runtime container privileges and could: - Read build secrets or application credentials. - Modify generated artif ...[truncated 322 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (35)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description centers on code generation: reading Dify DSL files, analyzing workflow structure, collecting missing inputs, and producing deployable standalone projects. The supplied code does none of that. It is a verification utility for an already generated Python project, using an analysis JSON and importing app.workflow.definition to validate structural and consistency checks. This is a materially different primary purpose, not merely a supporting helper for conversion, because the code chunk itself neither reads DSL YAML for conversion nor emits a project. Therefore the description does not accurately represent the actual behavior.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · assets/templates/node-express/.env.example (reported line 1)May include surrounding context.

text
# Copy to .env and fill in real values. Never commit .env.
APP_NAME=dify-workflow-service

# --- Required by workflow (regenerate this section from analysis.json) ---

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · assets/templates/python-fastapi/.env.example (reported line 1)May include surrounding context.

text
# Copy to .env and fill in real values. Never commit .env.
APP_NAME=dify-workflow-service

# --- Required by workflow (regenerate this section from analysis.json) ---

Possible Typosquatting: 'uvicorn' resembles popular package 'gunicorn'

High
Category
Supply Chain
Confidence
70% confidence
Finding

Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
| 节点输出 | `{{#node_id.var#}}` | 变量池 `(node_id, var)` |
| 系统变量 | `sys.query` `sys.files` `sys.user_id` `sys.conversation_id` `sys.dialogue_count` | 运行时注入的请求上下文 |
| 环境变量 | `{{#env.NAME#}}` | 进程环境变量 |
| 密钥 | `{{#secret.NAME#}}` | 进程环境变量,只写 .env 占位 |
| 会话变量 | conversation_variables 中的 name | 有状态存储(chatflow);无状态可降级 |
| 上下文 | llm 节点内 `{{#context#}}` | 知识检索结果拼接文本 |

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/codegen-patterns.md (reported line 91)May include surrounding context.

md
| 节点输出 | `{{#node_id.var#}}` | 变量池 `(node_id, var)` |
| 系统变量 | `sys.query` `sys.files` `sys.user_id` `sys.conversation_id` `sys.dialogue_count` | 运行时注入的请求上下文 |
| 环境变量 | `{{#env.NAME#}}` | 进程环境变量 |
| 密钥 | `{{#secret.NAME#}}` | 进程环境变量,只写 .env 占位 |
| 会话变量 | conversation_variables 中的 name | 有状态存储(chatflow);无状态可降级 |
| 上下文 | llm 节点内 `{{#context#}}` | 知识检索结果拼接文本 |

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/dsl-components.md (reported line 72)May include surrounding context.

md
| 节点输出 | `{{#node_id.var#}}` | 变量池 `(node_id, var)` |
| 系统变量 | `sys.query` `sys.files` `sys.user_id` `sys.conversation_id` `sys.dialogue_count` | 运行时注入的请求上下文 |
| 环境变量 | `{{#env.NAME#}}` | 进程环境变量 |
| 密钥 | `{{#secret.NAME#}}` | 进程环境变量,只写 .env 占位 |
| 会话变量 | conversation_variables 中的 name | 有状态存储(chatflow);无状态可降级 |
| 上下文 | llm 节点内 `{{#context#}}` | 知识检索结果拼接文本 |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs reading DSL files, writing generated projects, and using environment-backed secrets, but it declares no explicit tool scope or permission boundaries. That creates an overbroad capability surface where an agent could access arbitrary local files or secrets beyond the intended DSL conversion workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The app name at L006 is Chinese, and the workflow prompts later are also written in Chinese, indicating the skill is designed to operate in a single language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The system prompt at L193 instructs the model in Chinese and implicitly assumes Chinese-language operation. Because the file does not provide any language choice or explicit justification for a Chinese-only scope, this constitutes a language/locale policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The final answer prompt at L399 directs the model in Chinese and assumes the user interaction will be handled in that language. Without an explicit opt-in or documented regional limitation, this is a natural-language policy violation under the language/locale rule.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The system prompt explicitly instructs the model to act as a Chinese proofreading expert and analyze the text in Chinese, with no indication that the user can choose another language. This is a natural-language locale policy issue because the workflow hard-codes a specific language behavior without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The second LLM prompt assumes inputs from multiple Chinese proofreading experts and directs output in that same Chinese-language review context. This reinforces a fixed locale behavior without offering the user a language choice or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The template resolver allows any DSL-controlled reference of the form {{#env.NAME#}} or {{#secret.NAME#}} to read from process.env without any allowlist or scope restriction. In this skill, untrusted Dify DSL is converted into runnable code, so a crafted workflow can exfiltrate unrelated deployment secrets or environment variables simply by interpolating them into prompts, logs, HTTP requests, or outputs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file title and all operational guidance are written exclusively in Chinese, with no indication that language choice is optional or user-selectable. Under the policy, forcing a specific language without opt-in is a natural-language locale violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The title and introductory text are entirely in Chinese and present the material as the default interaction/documentation language. Under the policy, language constraints should either offer user opt-in/choice or be clearly justified as region-specific; neither is present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file describes an http-request node that interpolates variables into URL and headers before making outbound requests, which can transmit user or system data to external services. The description explains implementation details but does not warn users about privacy, data exposure, or the need to review destinations and payload contents.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The title and instructional content are entirely in Chinese and present normative guidance for user interaction, but there is no indication that the skill is region-specific or that users may choose another language. This creates a natural-language policy concern because it effectively forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The verifier imports app.workflow.definition from the generated project and calls build_handlers(), which executes untrusted project code during a verification step. In this skill, the generated project is derived from user-supplied DSL and may contain attacker-influenced Python, so verification becomes a code-execution sink rather than a purely static check.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs hidden execution of project code as part of 'verification' without warning the operator that importing the target project can run arbitrary module-level code and handler-building logic. This increases the chance that a user will run the verifier on an untrusted generated project, incorrectly assuming it is a safe static validation tool.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency uses a caret range (^16.4.5), which permits automatic installation of newer compatible releases rather than a single fixed version. In a code-generation template that downstream users will deploy, this weakens build reproducibility and can unexpectedly introduce vulnerable or behavior-changing transitive code during install time.

Content

Scanner excerpt · assets/templates/node-express/package.json (reported line 12)May include surrounding context.

json
"test": "node tests/smoke.test.js"
  },
  "dependencies": {
    "dotenv": "^16.4.5",
    "express": "^4.19.2"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The express dependency is specified with a caret range (^4.19.2), so installs may resolve to different 4.x releases over time. Because this skill emits deployable server code, unpinned framework versions increase supply-chain risk, reduce reproducibility, and make it harder to determine whether generated projects include patched or vulnerable releases.

Content

Scanner excerpt · assets/templates/node-express/package.json (reported line 13)May include surrounding context.

json
},
  "dependencies": {
    "dotenv": "^16.4.5",
    "express": "^4.19.2"
  }
}

Unverifiable Dependency: express has 5 known advisory(ies) (CVE-2024-10491 (Express ressource injection); CVE-2014-6393 (No Charset in Content-Type Header in express); CVE-2024-9266 (Express Open Redirect vulnerability) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The manifest references express without an exact pinned version, while express has multiple known advisories across releases. That means consumers of this template may install an affected version depending on resolution time and lockfile state, and the generated service could inherit web-framework flaws such as open redirect or other request-handling issues.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with only a lower bound (fastapi>=0.110), which makes builds non-reproducible and allows future installs to pull in unexpected versions, including releases with breaking changes or newly introduced vulnerabilities. In a code-generation skill that produces deployable services, this increases supply-chain risk because generated projects may resolve differently over time.

Content

Scanner excerpt · assets/templates/python-fastapi/requirements.txt (reported line 1)May include surrounding context.

text
fastapi>=0.110
uvicorn[standard]>=0.29
pydantic>=2.6
python-dotenv>=1.0

Unverifiable Dependency: fastapi has 3 known advisory(ies) (CVE-2021-32677 (Cross-Site Request Forgery (CSRF) in FastAPI); CVE-2021-32677 (FastAPI is a web framework for building APIs with Python 3.6+ based on standard ); CVE-2024-24762 (FastAPI is a web framework for building APIs with Python 3.8+ based on standard )), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

FastAPI has known security advisories, and because the manifest does not pin a version, there is no way to verify whether installations will land on an affected or remediated release. In a code-generation template, this is dangerous because every generated project inherits that ambiguity and may unknowingly deploy a vulnerable package.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.