Back to skill

Security audit

dify-flow-access

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-built to query a Dify knowledge base, but it ships a hardcoded API key and sends credentials and user queries to a default HTTP endpoint.

Review before installing. Do not use the packaged default credential; rotate or revoke it, require a user-provided secret, and configure an HTTPS Dify endpoint before sending real internal queries or conversation IDs.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dify-workflow.sh:8
Finding
Hardcoded Dify API Bearer Credential<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dify-workflow.sh:8-9`; duplicated in `SKILL.md:34-38` **Vulnerability Type**: Hardcoded secret **Risk Level**: High ### Vulnerable Code ```bash # Configuration from environment or defaults DIFY_BASE_URL="${DIFY_BASE_URL:-http://10.10.10.159/v1}" DIFY_API_KEY="${DIFY_API_KEY:-app-jUhDcPj3lcnEG04JW4gRsfyy}" ``` The same credential is disclosed in the documentation: ```markdown **Base URL**: `http://10.10.10.159/v1` **API Key**: `app-jUhDcPj3lcnEG04JW4gRsfyy` ``` ### Technical Analysis A live-looking Dify bearer token is embedded directly in both the executable script and its documentation. The environment-variable fallback does not protect the credential: whenever `DIFY_API_KEY` is unset, the script automatically uses the exposed value. Anyone who can read the distributed Skill package, a repository copy, an archive, or relevant build artifacts can recover the token. Because bearer tokens confer access through possession, no additional authentication material is necessarily required to reuse it. ### Attack Path 1. An attacker obtains a copy of the Skill package or reads its repository. 2. The attacker extracts the hardcoded API key and internal Dify service address. 3. If the Dify endpoint is reachable from the attacker's position, the attacker submits API requests with: `Authorization: Bearer app-jUhDcPj3lcnEG04JW4gRsfyy`. 4. The attacker invokes the API capabilities authorized for the associated Dify application. 5. The attacker may repeat requests until the credential is revoked, expires, or is otherwise restricted. Successful exploitation depends on network access to the configured service and the permissions assigned to the exposed key. ### Impact Assessment The exposed credential may permit unauthorized knowledge-base queries, ChatApp requests, workflow execution, resource consumption, and access to application responses. The precise scope is limited by the Dify application's per ...[truncated 171 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed credential immediately; removing it from the current files does not invalidate copies in repository history or distributed artifacts. 2. Remove the API key from both `scripts/dify-workflow.sh` and `SKILL.md`. 3. Require `DIFY_API_KEY` to be provided at runtime and terminate safely if it is absent: ```bash : "${DIFY_API_KEY:?DIFY_API_KEY must be supplied through a protected secret store}" ``` 4. Supply the key through an approved secret manager or protected runtime environment rather than source control. 5. Restrict the replacement credential to the minimum required Dify application permissions. 6. Apply network-level restrictions, expiration, rotation, and usage monitoring where supported. 7. Search repository history, release archives, logs, and package registries for the exposed value and purge it where feasible. 8. Add automated secret scanning to the development and release pipelines. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dify-workflow.sh:115
Finding
Dify Credentials and Query Data Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dify-workflow.sh:8`, `scripts/dify-workflow.sh:115-124`; the insecure default is also documented at `SKILL.md:34-36` **Vulnerability Type**: Cleartext transmission of sensitive information **Risk Level**: High ### Vulnerable Code ```bash # Configuration from environment or defaults DIFY_BASE_URL="${DIFY_BASE_URL:-http://10.10.10.159/v1}" ``` ```bash # Execute request with timeout echo "" >&2 echo "🚀 Sending request..." >&2 RESPONSE=$(curl -s -X POST "$ENDPOINT" \ -H "Authorization: Bearer ${DIFY_API_KEY}" \ -H "Content-Type: application/json" \ --max-time "$DEFAULT_TIMEOUT" \ --data-binary "${WORKFLOW_PAYLOAD}") ``` ### Technical Analysis The default API URL uses unencrypted HTTP while the request contains a bearer credential and potentially sensitive user queries, workflow parameters, conversation identifiers, and responses. HTTP provides neither transport confidentiality nor cryptographic server authentication. An attacker able to observe or alter traffic on the relevant network path can capture the authorization header and request contents. An active network attacker may also modify requests or responses because the client has no TLS integrity protection. The script permits `DIFY_BASE_URL` overrides but does not require HTTPS, so insecure configurations remain accepted. ### Attack Path 1. A user runs the Skill with its default `http://10.10.10.159/v1` URL. 2. The script sends the bearer key, payload, and conversation information over plaintext HTTP. 3. An attacker with access to the local network, gateway, proxy, virtual network, or another relevant traffic-observation point captures the request. 4. The attacker reads the bearer token and sensitive request contents. 5. If the service is reachable, the attacker replays the token in independent requests. 6. Alternatively, an active attacker modifies API traffic or impersonates the endpoint and supplies manipulated responses. ...[truncated 506 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Configure the Dify service with HTTPS and a certificate issued by a trusted internal or public certificate authority. 2. Replace the default URL with an HTTPS endpoint. 3. Validate the URL scheme before transmitting credentials and reject plaintext HTTP by default: ```bash if [[ "$DIFY_BASE_URL" != https://* ]]; then echo "DIFY_BASE_URL must use HTTPS" >&2 exit 1 fi ``` 4. Retain curl's default certificate verification and do not introduce `--insecure` or equivalent bypasses. 5. If a development-only HTTP override is unavoidable, require an explicit opt-in and ensure it cannot be enabled in production. 6. Rotate the currently exposed bearer key because it may already have traversed untrusted network paths. 7. Minimize API-key privileges and add server-side network allowlists, expiry controls, audit logging, and anomalous-use detection. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dify-workflow.sh:83
Finding
JSON Request Injection through Unescaped Command-Line Input<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dify-workflow.sh:83-100` **Vulnerability Type**: Improper construction of JSON from untrusted input **Risk Level**: Medium ### Vulnerable Code ```bash # Prepare request body based on mode if [ "$USE_CHAT_MODE" = true ]; then # ChatApp mode with conversation_id if [ -n "$CONVERSATION_ID" ]; then WORKFLOW_PAYLOAD="{\"inputs\": {}, \"query\": \"${QUERY}\", \"conversation_id\": \"${CONVERSATION_ID}\", \"response_mode\": \"${REQUEST_MODE}\", \"user\": \"openclaw-user\", \"files\": []}" else # ChatApp mode without conversation_id (auto-generate) WORKFLOW_PAYLOAD="{\"inputs\": {}, \"query\": \"${QUERY}\", \"response_mode\": \"${REQUEST_MODE}\", \"user\": \"openclaw-user\", \"files\": []}" fi elif [ -n "$WORKFLOW_ID" ]; then # Workflow mode with workflow ID WORKFLOW_PAYLOAD="{\"workflow_id\": \"${WORKFLOW_ID}\", \"inputs\": {\"query\": \"${QUERY}\"}, \"response_mode\": \"${REQUEST_MODE}\", \"user\": \"openclaw-user\"}" else # Generic workflow execution (may not work without workflow_id) WORKFLOW_PAYLOAD="{\"inputs\": {\"query\": \"${QUERY}\"}, \"response_mode\": \"${REQUEST_MODE}\", \"user\": \"openclaw-user\"}" fi ``` ### Technical Analysis The script interpolates `QUERY`, `WORKFLOW_ID`, and `CONVERSATION_ID` directly into JSON string literals without applying JSON escaping. Input containing quotation marks, backslashes, newlines, or other control characters can produce malformed JSON. Crafted values may also terminate the intended JSON string and insert additional properties or nested content. Whether duplicate or injected properties alter behavior depends on the Dify parser and endpoint schema, but the client does not preserve the intended boundary between data and JSON structure. This is request-body injection rather than shell command injection: the variables remain quoted when passed to curl, and the reviewed code does not evaluate them as s ...[truncated 1213 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stop constructing JSON through shell string concatenation. 2. Use a proper serializer such as Python's `json` module or `jq --arg`, ensuring all externally supplied values are encoded as JSON strings. 3. For example, construct the workflow payload with `jq`: ```bash WORKFLOW_PAYLOAD=$(jq -n \ --arg workflow_id "$WORKFLOW_ID" \ --arg query "$QUERY" \ --arg response_mode "$REQUEST_MODE" \ '{ workflow_id: $workflow_id, inputs: {query: $query}, response_mode: $response_mode, user: "openclaw-user" }') ``` 4. Build the chat payload similarly, adding `conversation_id` only when it is present. 5. Validate `WORKFLOW_ID` and `CONVERSATION_ID` against the exact formats documented by Dify before serialization. 6. Add tests covering quotation marks, backslashes, multiline text, Unicode, control characters, and JSON-shaped input. 7. Consider validating the generated payload with a JSON parser before sending it. ]]>
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Missing User Warnings

High
Confidence
95% confidence
Finding
The skill describes multi-turn querying and workflow execution against an internal HTTP API but does not warn users that their prompts and conversation IDs/content may be transmitted to another service. This omission is dangerous because users may share sensitive internal data under the assumption it stays local, while the skill forwards it over an internal endpoint with no clear consent or sensitivity notice.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script embeds a default Dify API key directly in the code and uses it automatically for authenticated requests. Anyone with access to the script can extract and reuse the credential, potentially invoking the remote app, consuming paid resources, accessing protected workflows, or pivoting into connected data sources.

Context Leakage

High
Category
Data Exfiltration
Content
print("ERROR_NO_ANSWER")
        sys.exit(1)
    
    # Extract conversation_id for multi-turn support
    conv_id = data.get("conversation_id", "")
    
    # Output using a delimiter that won't appear in normal text
Confidence
75% confidence
Finding
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger conditions are overly broad and map ordinary user language to an action that sends content to an internal API, increasing the chance of unintentional activation. In a skill that can transmit prompts and conversation context to a backend service, broad triggers create a security and privacy risk because users may not realize their request is being forwarded externally.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The configuration section shows how to set API credentials but fails to warn that the key is sensitive and must not be exposed, logged, or committed. In combination with the included default key and internal service URL, this normalizes insecure secret handling and increases the likelihood of credential leakage and misuse.

Context-Inappropriate Capability

Medium
Confidence
99% confidence
Finding
The skill embeds a live default API key directly in documentation/configuration, giving any user of the skill an immediate authenticated capability to an internal Dify service. Hardcoded credentials are dangerous because they can be copied, reused outside intended scope, and remain valid long after the skill is distributed, enabling unauthorized access to internal knowledge bases or workflows.

External Transmission

Medium
Category
Data Exfiltration
Content
# Execute request with timeout
echo "" >&2
echo "🚀 Sending request..." >&2
RESPONSE=$(curl -s -X POST "$ENDPOINT" \
    -H "Authorization: Bearer ${DIFY_API_KEY}" \
    -H "Content-Type: application/json" \
    --max-time "$DEFAULT_TIMEOUT" \
Confidence
94% confidence
Finding
This curl invocation sends data and a bearer token to an external service, and the configured default endpoint is an internal-looking IP over unencrypted HTTP. In the context of an agent skill, that is dangerous because arbitrary user input is exfiltrated off-host and authentication material may be exposed in transit or misused by the remote service.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script transmits user-supplied query content and optional conversation context to a remote endpoint by default, and the default base URL uses plain HTTP rather than HTTPS. This creates both a privacy risk from undisclosed data sharing and a transport-security risk, because sensitive prompts and conversation IDs may be intercepted or logged by intermediaries.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
The usage examples are exclusively written with Chinese query phrases such as '你好' and '如何部署?', which signals a language-specific default interaction pattern. There is no accompanying note that other languages are supported or that Chinese is merely illustrative, so this can be read as an implicit language preference without user opt-in.

Static analysis

No suspicious patterns detected.