Dify
Static analysis for Dify workflow exports to detect loop vulnerabilities, DSL security issues, and plugin misconfigurations.
Quick Start
# Export workflow DSL from Dify, then scan
inkog scan ./workflowsWhat Inkog Detects
| Finding | Severity | Description |
|---|---|---|
| Loop Without Limit | CRITICAL | Loop node without max_iterations |
| Iteration Unbounded | HIGH | Iteration node without bounds |
| Plugin Secrets | CRITICAL | Secrets exposed in plugin config |
| DSL Injection | HIGH | User input in DSL expressions |
| Code Block Risk | CRITICAL | Dangerous code in code blocks |
Loop Node Without Limits
Dify Loop nodes without iteration limits run forever.
Vulnerable
Loop runs indefinitely
# workflow.dsl.yaml
version: '1'
workflow:
nodes:
- id: loop_1
type: loop
data:
loop_type: while
condition: "{{output.continue}}"
# No max_iterations!
- id: llm_1
type: llm
data:
model: gpt-4Secure
Explicit iteration limit
# workflow.dsl.yaml
version: '1'
workflow:
nodes:
- id: loop_1
type: loop
data:
loop_type: while
condition: "{{output.continue}}"
max_iterations: 10
break_on_error: true
- id: llm_1
type: llm
data:
model: gpt-4
timeout: 30Iteration Node Bounds
Iteration nodes processing unbounded lists.
Vulnerable
Unbounded iteration over user list
nodes:
- id: iteration_1
type: iteration
data:
iterator: "{{input.items}}"
# Processes ALL items, no limit
- id: api_call
type: http_request
data:
url: "https://api.example.com"Secure
Limited items with parallelism control
nodes:
- id: limit_items
type: code
data:
code: |
items = input.items[:100] # Max 100 items
return {"items": items}
- id: iteration_1
type: iteration
data:
iterator: "{{limit_items.items}}"
max_parallel: 5
timeout_per_item: 10
- id: api_call
type: http_request
data:
url: "https://api.example.com"
timeout: 10Plugin Secret Exposure
Plugin configurations with exposed secrets.
Vulnerable
Hardcoded credentials
plugins:
- id: openai_plugin
type: model_provider
config:
api_key: "sk-abc123..."
organization: "org-xyz"
- id: database_plugin
type: external
config:
connection_string: "postgres://user:password@host/db"Secure
Environment and secrets references
plugins:
- id: openai_plugin
type: model_provider
config:
api_key: "{{env.OPENAI_API_KEY}}"
organization: "{{env.OPENAI_ORG}}"
- id: database_plugin
type: external
config:
connection_string: "{{secrets.DATABASE_URL}}"DSL Expression Injection
User input in DSL expressions can be exploited.
Vulnerable
User controls DSL expressions
nodes:
- id: template_1
type: template
data:
template: |
Process this: {{input.user_query}}
Execute: {{input.command}}Secure
Sanitized input without DSL syntax
nodes:
- id: sanitize
type: code
data:
code: |
import re
query = input.user_query
# Remove DSL syntax
query = re.sub(r'{{.*?}}', '', query)
# Remove dangerous patterns
query = re.sub(r'(execute|eval|import)', '', query, flags=re.I)
return {"safe_query": query[:500]}
- id: template_1
type: template
data:
template: |
Process this: {{sanitize.safe_query}}Code Block Risks
Code blocks with dangerous operations.
Vulnerable
Shell command execution
nodes:
- id: code_1
type: code
data:
language: python
code: |
import os
import subprocess
result = subprocess.run(input.command, shell=True)
return {"output": result.stdout}Secure
Safe data transformation only
nodes:
- id: code_1
type: code
data:
language: python
code: |
import json
# Safe data processing only
data = json.loads(input.data)
processed = [item.strip() for item in data if item]
return {"output": processed[:100]}How to Export Workflows
To scan Dify workflows:
- From UI: Workflow → Settings → Export DSL
- Via API:
# Export workflow DSL
curl -X GET "http://localhost/api/apps/{app_id}/export" \
-H "Authorization: Bearer $API_KEY" \
-o workflow.dsl.yamlThen scan:
inkog scan ./workflow.dsl.yamlKnowledge Base Risks
Knowledge base with untrusted document sources.
Vulnerable
User-controlled knowledge source
knowledge_bases:
- id: kb_1
type: external
config:
source_url: "{{input.url}}"
sync_enabled: trueSecure
Fixed approved source
knowledge_bases:
- id: kb_1
type: internal
config:
source_path: "./approved_docs"
allowed_types: [".txt", ".pdf", ".md"]
max_file_size: 10485760 # 10MB
sync_enabled: falseAgent Configuration
Agent nodes with dangerous tool access.
Vulnerable
Code interpreter and browser access
nodes:
- id: agent_1
type: agent
data:
tools:
- type: code_interpreter
enabled: true
- type: web_browser
enabled: trueSecure
Safe tools only with limits
nodes:
- id: agent_1
type: agent
data:
max_iterations: 10
timeout: 60
tools:
- type: knowledge_retrieval
enabled: true
config:
knowledge_base_id: kb_1
- type: calculator
enabled: trueBest Practices
- Set
max_iterationson all Loop nodes - Limit iteration items before processing
- Use environment variables for secrets
- Sanitize user input before DSL templates
- Avoid code blocks with
osorsubprocess - Restrict agent tools to safe operations
CLI Examples
# Scan Dify exports
inkog scan ./workflows
# Check DSL files
inkog scan . -severity critical
# JSON output
inkog scan . -output jsonRelated
- n8n - Similar workflow platform
- Resource Exhaustion
- Code Injection
Last updated on