Back to skill

Security audit

Workflow Automation Cn

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent automation generator, but it needs review because it can lead agents to create scheduled scripts that call external services, change files, and publish content without strong scoping or confirmation steps.

Install only if you are comfortable reviewing generated automations before activation. Require the agent to show the full script, schedule, file paths, external endpoints, message contents, and credentials handling before adding anything to HEARTBEAT.md; prefer environment variables or a secret store and private per-workflow state directories instead of hardcoded tokens or /tmp files.

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:110
Finding

Predictable Shared Temporary File Used for Price State

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 110-128
Vulnerability Type: Predictable temporary file and unsafe symlink following
Risk Level: Medium

Vulnerable Code:

python
LAST_PRICE_FILE = "/tmp/last_price.json"

def get_last_price():
    """获取上次价格"""
    try:
        with open(LAST_PRICE_FILE) as f:
            return json.load(f)["price"]
    except:
        return None

def save_price(price):
    """保存价格"""
    with open(LAST_PRICE_FILE, "w") as f:
        json.dump({"price": price}, f)

Technical Analysis

The generated price-monitoring template stores persistent state at a fixed, predictable path in the shared /tmp directory. The call to open(LAST_PRICE_FILE, "w") follows symbolic links and truncates an existing destination before writing.

On systems where temporary-directory symlink protections are absent, disabled, or inapplicable, another local user can prepare this pathname as a symbolic link to a file writable by the automation account. File-path collisions can also let another process corrupt the stored price. The unrestricted except clause suppresses errors caused by malformed or attacker-controlled state, making interference harder to detect.

Attack Path

  1. The attacker determines that the generated workflow uses /tmp/last_price.json.
  2. Before the first workflow run, the attacker creates that path as a symbolic link to another file writable by the automation account.
  3. The scheduled price monitor executes save_price().
  4. Python follows the symbolic link and opens the linked target in truncating write mode.
  5. The target is overwritten with attacker-influenced workflow state, subject to the automation account's existing filesystem permissions.

Alternatively, an attacker able to manipulate the temporary file can insert malformed or false price state. This can suppress alerts, trigger misleading alerts, or cause the code to silently d ...[truncated 488 chars]

Remediation
View remediation

Remediation Suggestions

  • Store persistent workflow state in a private application directory rather than /tmp, such as ~/.local/state/openclaw, with directory permissions set to 0700.
  • Create state files with permissions no broader than 0600.
  • Refuse symbolic-link destinations by using platform-appropriate no-follow semantics, such as os.open() with O_NOFOLLOW where supported.
  • Write to a securely created temporary file in the same private directory, flush and synchronize it, and atomically replace the destination with os.replace().
  • Validate that the destination is a regular file owned by the expected user before reading it.
  • Replace the unrestricted except: clause with specific exceptions such as FileNotFoundError, json.JSONDecodeError, and OSError, and log unexpected failures.
  • Use a unique state filename per workflow to prevent collisions.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:227
Finding

Predictable Shared Temporary File Used for API Results

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 227-242
Vulnerability Type: Predictable temporary file and unsafe symlink following
Risk Level: Medium

Vulnerable Code:

python
API_URL = "https://api.example.com/endpoint"
RESULT_FILE = "/tmp/api_result.json"

def call_api():
    """调用 API"""
    resp = requests.get(API_URL, timeout=30)
    return resp.json()

def process_result(data):
    """处理结果"""
    # 自定义处理逻辑
    return data

def save_result(data):
    """保存结果"""
    with open(RESULT_FILE, "w") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

Technical Analysis

The API workflow template writes results to the fixed path /tmp/api_result.json. Because this is a predictable name in a shared temporary directory and the normal Python file-opening operation follows symbolic links, the destination can be exposed to symlink attacks and cross-process collisions.

If the API response includes sensitive information, the template also does not explicitly restrict file permissions. The resulting confidentiality impact depends on the process umask and existing pathname ownership and permissions.

Attack Path

  1. The attacker learns or predicts the fixed result path /tmp/api_result.json.
  2. Before the workflow writes its result, the attacker creates the pathname as a symbolic link to another file writable by the automation account.
  3. The scheduled API workflow retrieves response data and invokes save_result().
  4. The open(..., "w") operation follows the link and truncates the linked target.
  5. The API result is written into that target under the automation account's privileges.

In a collision scenario, another local process can also pre-create or manipulate the predictable file, potentially corrupting results or exposing stored response data where effective permissions allow access.

Impact Assessment

An attacker may cause corruption or rep ...[truncated 336 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace the shared /tmp path with a private, workflow-specific state directory owned by the automation account and configured with mode 0700.
  • Create result files with mode 0600, independent of the process's default umask.
  • Prevent symbolic-link traversal with O_NOFOLLOW or an equivalent safe-file API where supported.
  • Use tempfile.NamedTemporaryFile() in the private destination directory and atomically install the completed result with os.replace().
  • Verify that an existing result path is a regular file owned by the expected account before accessing it.
  • Assign unique paths to separate workflow instances to prevent accidental collisions.
  • Assess whether API responses contain secrets and avoid persisting unnecessary sensitive fields.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill name and entire description are Chinese-only, and the usage examples and instructions assume Chinese interaction without stating that other languages are supported or offering opt-in language selection. This can violate language/locale policy when a skill implicitly forces a specific language without user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description presents the tool as a simple workflow generator but does not clearly warn that generated automations may perform network requests, write local files, move content, or publish externally. This can mislead users about the operational and data-security consequences of using the skill, especially because the examples include recurring execution and outbound transmissions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The invocation examples are broad natural-language commands that can cause the agent to generate and configure executable automations without clear boundaries, confirmation gates, or scope restrictions. In an automation skill, this increases the chance of unintended file changes, scheduled execution, or external actions being created from ambiguous user input.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly recommends using environment variables for sensitive data, but the Telegram example hardcodes credential placeholders directly in source code. In practice, users often replace placeholders with real secrets and commit or share the script, which can lead to credential leakage and unauthorized use of the bot/account.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The Telegram notification example transmits content to an external service, which is expected for a notification workflow but still creates a real data egress path. Because the skill generates runnable automation, users may unknowingly send sensitive reports, identifiers, or operational data to third-party services on a schedule.

Content

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

md
"""发送通知到 Telegram"""
    bot_token = "YOUR_BOT_TOKEN"
    chat_id = "YOUR_CHAT_ID"
    url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
    requests.post(url, data={
        "chat_id": chat_id,
        "text": message

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
def get_price():
    """获取当前价格"""
    resp = requests.get("https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT")
    return float(resp.json()["price"])

def get_last_price():

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

The generic API-calling template encourages scheduled requests to an arbitrary external endpoint and stores the results locally, but does not include any warning, trust boundary guidance, or restrictions on what data may be sent or received. In a code-generating automation skill, this can normalize creating unattended integrations that exfiltrate data or interact with untrusted services.

Content

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

md
import requests
import json

API_URL = "https://api.example.com/endpoint"
RESULT_FILE = "/tmp/api_result.json"

def call_api():

Static analysis

No suspicious patterns detected.