Skip to Content

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 ./workflows

What Inkog Detects

FindingSeverityDescription
Loop Without LimitCRITICALLoop node without max_iterations
Iteration UnboundedHIGHIteration node without bounds
Plugin SecretsCRITICALSecrets exposed in plugin config
DSL InjectionHIGHUser input in DSL expressions
Code Block RiskCRITICALDangerous 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-4
Secure
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: 30

Iteration 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: 10

Plugin 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:

  1. From UI: Workflow → Settings → Export DSL
  2. Via API:
# Export workflow DSL curl -X GET "http://localhost/api/apps/{app_id}/export" \ -H "Authorization: Bearer $API_KEY" \ -o workflow.dsl.yaml

Then scan:

inkog scan ./workflow.dsl.yaml

Knowledge 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: true
Secure
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: false

Agent 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: true
Secure
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: true

Best Practices

  1. Set max_iterations on all Loop nodes
  2. Limit iteration items before processing
  3. Use environment variables for secrets
  4. Sanitize user input before DSL templates
  5. Avoid code blocks with os or subprocess
  6. 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 json
Last updated on