Back to skill

Security audit

coze-workflow-api

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but its examples use a Coze personal access token in ways that could expose the token or saved workflow results.

Review before installing. Use this only for Coze workflows you trust, avoid sending secrets or regulated data as workflow parameters, use a narrowly scoped PAT where possible, rotate the PAT if exposed, and save any workflow output to a private path with restrictive permissions instead of the documented /tmp file.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:25
Finding

Bearer Token Exposed Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 25–29; repeated at lines 43–47 and 70–74
Vulnerability Type: Bearer token exposure through process arguments
Risk Level: Medium

Vulnerable Code

bash
curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{

Technical Analysis

The shell expands $COZE_PAT_KEY before starting curl, placing the complete authorization header in the process argument vector. While the request is transmitted over HTTPS, local process-inspection interfaces, diagnostic utilities, monitoring agents, audit systems, or process telemetry may capture the expanded command line while the request is running.

The same insecure authorization pattern appears in all three documented curl examples. The file does not hardcode an actual credential, but its recommended invocation method can expose a user-supplied PAT to local observers or logs.

Attack Path

  1. A user exports a valid Coze PAT as COZE_PAT_KEY.
  2. The user runs one of the documented curl commands.
  3. The shell expands the variable into Authorization: Bearer <token> in the curl argument vector.
  4. A local user, privileged monitoring process, or command-line telemetry system observes or records the process arguments.
  5. The observer extracts the PAT and submits authenticated requests to the Coze API.
  6. The stolen token remains usable until it expires or is revoked.

Exploitation depends on the operating system's process-visibility controls and the attacker's local access or access to collected process telemetry.

Impact Assessment

A stolen PAT grants the attacker the permissions assigned to that token. This may permit unauthorized workflow execution, access to workflow-generated data, consumption of account quotas, and actions available through ...[truncated 176 chars]

Remediation
View remediation

Remediation Suggestions

  • Avoid passing bearer tokens directly in command-line arguments.

  • Use a client or wrapper that constructs the authorization header in memory rather than in the process argument vector.

  • If curl must be used, place sensitive options in a temporary configuration file created with restrictive permissions:

    bash
    umask 077
    config_file="$(mktemp)"
    trap 'rm -f "$config_file"' EXIT
    
    printf '%s\n' \
      'header = "Content-Type: application/json"' \
      "header = \"Authorization: Bearer ${COZE_PAT_KEY}\"" \
      > "$config_file"
    
    curl --silent --show-error \
      --location \
      --request POST \
      --config "$config_file" \
      --max-time 120 \
      --data-raw '{
        "workflow_id": "your_workflow_id",
        "parameters": {
          "key": "value"
        }
      }' \
      'https://api.coze.com/v1/workflow/stream_run'
    
  • Ensure the temporary configuration file is deleted on normal exit and interruption.

  • Prevent shell tracing around secret-bearing operations and configure monitoring systems to redact authorization headers.

  • Use narrowly scoped, short-lived PATs where supported.

  • Revoke and rotate any token suspected of having been exposed.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:42
Finding

Predictable Shared Temporary File Allows Output Disclosure or File Clobbering

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 42–52
Vulnerability Type: Unsafe predictable temporary file
Risk Level: Medium

Vulnerable Code

bash
curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "workflow_id": "your_workflow_id",
    "parameters": {
      "key": "value"
    }
  }' \
  --max-time 120 > /tmp/coze_result.txt

Technical Analysis

The command writes workflow output to the fixed path /tmp/coze_result.txt. Shared temporary directories are generally writable by multiple users. A predictable filename can therefore introduce two security problems:

  1. Another local user may pre-create the path as a symbolic link or other filesystem object. The shell redirection can follow that link and truncate or overwrite its target when filesystem protections permit it.
  2. The newly created result file receives permissions derived from the user's current umask. With a common permissive umask, workflow results may be readable by other local users.

Modern systems may mitigate some cross-user symbolic-link attacks with sticky-directory and protected-symlink settings, but the documentation does not require or verify these protections. The pattern remains unsafe and non-portable.

Attack Path

  1. An attacker predicts that the user will save results to /tmp/coze_result.txt.
  2. Before execution, the attacker creates that path as a symbolic link or suitably prepared file.
  3. The user runs the documented command.
  4. Shell redirection opens the predictable path before curl writes its response.
  5. If the platform's temporary-directory protections allow the operation, the response is written to the attacker-selected target or another file is truncated.
  6. Alternatively, if the path is newly created with permissive permissio ...[truncated 759 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace the fixed path with a securely generated temporary file.
  • Set a restrictive umask before creating files containing workflow output.
  • Validate successful file creation and remove the file after use.
  • Do not execute the command with elevated privileges.
  • Prefer a private application data directory when results must persist.

Example hardened pattern:

bash
umask 077
result_file="$(mktemp "${TMPDIR:-/tmp}/coze_result.XXXXXX")" || exit 1
trap 'rm -f "$result_file"' EXIT

curl --silent --show-error \
  --location \
  --request POST \
  'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "workflow_id": "your_workflow_id",
    "parameters": {
      "key": "value"
    }
  }' \
  --max-time 120 > "$result_file"

If the output must remain after the command exits, move it from the private temporary file to an explicitly selected destination with permissions set to 0600.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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 (6)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs users to send workflow parameters and a PAT-authenticated request to an external third-party API, but it does not clearly warn that arbitrary input data will leave the local environment and be processed remotely. This creates a real risk of accidental exfiltration of sensitive data or misuse of a privileged token, especially because the examples normalize direct transmission without privacy or trust guidance.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This command performs a live POST request to an external API and includes both user-supplied workflow parameters and a bearer token for authentication. While external API use is the intended purpose of the skill, it is still security-relevant because it can transmit sensitive input off-system and authorize actions under the user's Coze account.

Content

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

使用方法

直接使用 curl

bash
curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

Referencing the external Coze API endpoint confirms that this skill is designed to communicate with a third-party service. In context, this is not inherently malicious, but it is security-significant because users may not realize data is leaving their environment and being handled under a remote trust boundary.

Content

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

直接使用 curl

bash
curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This variant saves the remote response to a local file after contacting the external API, combining outbound data transfer with local persistence. That can amplify risk by both exposing input externally and leaving potentially sensitive returned data in /tmp, which may be accessible to other local users or processes depending on system configuration.

Content

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

保存结果到文件

bash
curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The explicit api.coze.com endpoint in the example marks a concrete third-party transmission target. In a skill specifically meant to call that service this is expected, but it still constitutes a real security concern because it defines a remote destination for authenticated data exchange without corresponding cautionary guidance.

Content

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

bash
export COZE_PAT_KEY="your_pat_token_here"

curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The explicit api.coze.com endpoint in the example marks a concrete third-party transmission target. In a skill specifically meant to call that service this is expected, but it still constitutes a real security concern because it defines a remote destination for authenticated data exchange without corresponding cautionary guidance.

Content

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

bash
export COZE_PAT_KEY="your_pat_token_here"

curl -s --location --request POST 'https://api.coze.com/v1/workflow/stream_run' \
  --header "Authorization: Bearer $COZE_PAT_KEY" \
  --header 'Content-Type: application/json' \
  --data-raw '{