Back to skill

Security audit

Openclaw Workflow Publish

Security checks for vulnerabilities and agentic risk

Overview

This is a powerful workflow engine whose automation features are mostly disclosed, but it grants broad local code, filesystem, environment, network, messaging, and session authority without enough containment or user control.

Install only if you trust the workflow YAML you will run and the local environment is not holding sensitive secrets. Treat workflows as code: review them before execution, avoid untrusted files, run with a low-privilege account, avoid exposing API keys in environment variables, and be careful with HTTP, message, script, code, and subagent nodes.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (7)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/engine/sandbox.py:29
Finding

Python Code Node Sandbox Permits Arbitrary Filesystem Access and Unbounded Execution

Content
View full analysis
SandboxResult: ``` ```python namespace: Dict[str, Any] = dict(variables) namespace["ctx_export"] = ctx_export namespace["__builtins__"] = dict(SAFE_BUILTINS) namespace["__builtins__"]["__import__"] = _safe_import old_stdout = sys.stdout try: sys.stdout = captured exec(compile(code, "", "exec"), namespace) ``` ### Technical Analysis The `code` node is described as executing Python in a sandbox, but the sandbox exposes the native `open()` function and allows importing `pathlib`. Consequently, workflow code can read, create, overwrite, or truncate any file accessible to the workflow process. Execution occurs through in-process `exec()`, so the code shares the interpreter, memory, privileges, and resources of the workflow engine. Although `execute_code()` accepts a `timeout` parameter, that parameter is never enforced. A workflow can therefore execute an infinite loop, consume excessive memory, or otherwise block the engine indefinitely. Restricting imports does not establish a security boundary when powerful filesystem primitives and host objects remain available. ### Attack Path 1. An attacker supplies or modifies a workflow containing a `code` node. 2. The node executes Python such as: ```python result = open("/home/user/.openclaw/openclaw.json").read() ``` 3. The engine reads the file with the current user's privileges. 4. The result becomes workflow output and may subsequently be logged, persisted, sent to an Agent, or transmitted through an HTTP or message node. For denial of service, the attacker can in ...[truncated 718 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/engine/context.py:132
Finding

Unrestricted Environment Variable Interpolation Enables Secret Exfiltration

Content
View full analysis
= 2: return os.environ.get(parts[1]) ``` ```python def run_http(step: dict, ctx: Context, log: LogFunc, bridge: "GatewayBridge" = None) -> NodeResult: """发起 HTTP 请求""" url = ctx.resolve(step.get("url", "")) if not url: return NodeResult(success=False, error="http 节点: 缺少 url") method = (step.get("method") or "GET").upper() headers = ctx.resolve(step.get("headers", {})) body = ctx.resolve(step.get("body")) params = ctx.resolve(step.get("params", {})) timeout = step.get("timeout", 30) # URL 参数 if params: url += ("&" if "?" in url else "?") + urllib.parse.urlencode(params) log(f"HTTP {method} {url}", "INFO") try: data = None if body is not None: if isinstance(body, (dict, list)): data = json.dumps(body, ensure_ascii=False).encode("utf-8") headers.setdefault("Content-Type", "application/json") else: data = str(body).encode("utf-8") req = urllib.request.Request(url, data=data, method=method) for k, v in headers.items(): req.add_header(k, str(v)) with urllib.request.urlopen(req, timeout=timeout) as resp: ``` ### Technical Analysis The template resolver permits a workflow to read any environment variable through `{{env.VARIABLE_NAME}}`. The HTTP node independently permits requests to arbitrary URLs with resolved values in the URL, query parameters, headers, and body. No environment-variable allowlist, destination allowlist, secret-provider boundary, user confirmation, or output redaction is applied. These two features form a direct secret-exfiltration pri ...[truncated 1299 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/engine/nodes.py:55
Finding

Shell Command Injection Through Unquoted Workflow Interpolation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/engine/bridge.py:35
Finding

OpenClaw Gateway Authentication Token Is Exposed in Process Arguments

Content
View full analysis
"GatewayConfig": """从 openclaw.json 读取配置""" config_path = Path(os.path.expanduser("~/.openclaw/openclaw.json")) if not config_path.exists(): return cls() try: with open(config_path, "r") as f: data = json.load(f) gw = data.get("gateway", {}) auth = gw.get("auth", {}) return cls( port=gw.get("port", 18789), token=auth.get("token", ""), ) ``` ```python cmd = ["openclaw", "gateway", "call", method, "--json"] cmd.extend(["--params", json.dumps(params, ensure_ascii=False)]) cmd.extend(["--timeout", str(timeout_ms)]) if self.config.token: cmd.extend(["--token", self.config.token]) if expect_final: cmd.append("--expect-final") timeout_sec = (timeout_ms / 1000) + 15 try: result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout_sec, ) ``` ### Technical Analysis The bridge reads the Gateway authentication token from `~/.openclaw/openclaw.json` and appends it directly to the child process's argument vector using `--token`. Command-line arguments can be observable through operating-system process inspection, endpoint monitoring, diagnostic tooling, process accounting, or crash collection. The exposure exists for the lifetime of each Gateway CLI subprocess. The code does not intentionally transmit the token to an unrelated external destination, but argv is not an appropriate secret transport mechanism when a safer authenticated local channel is available. ### Attack Path 1. A workflow invokes an LLM, Agent, Skill, subagent, or Gateway health operation. 2. The bridge launches: ```text openclaw gateway call ... --token ...[truncated 717 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/engine/bridge.py:916
Finding

Workflow Cleanup Can Delete Sessions Belonging to Other Concurrent Runs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/engine/engine.py:749
Finding

Sensitive Workflow Context and Results Are Persisted in Plaintext

Content
View full analysis
Dict[str, Any]: """导出可序列化的上下文快照""" return { "globals": copy.deepcopy(self._globals), "step_outputs": copy.deepcopy(self._step_outputs), "scopes": copy.deepcopy(self._scopes), } ``` ### Technical Analysis After workflow steps execute, the engine serializes full run records and snapshots to plaintext JSON. Snapshots contain global variables, local scopes, and all step outputs. These values can include API responses, Agent messages, personal communications, report contents, tokens, and other confidential data. The implementation does not perform secret classification or redaction. It also provides no explicit no-persistence mode, retention limit, or cleanup policy. Files are created using ambient permissions rather than explicitly enforcing owner-only access. Because snapshots are written after steps, even data needed ...[truncated 897 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding

Unpinned Dependencies Permit Unreviewed Future Package Versions

Content
View full analysis
=6.0 streamlit>=1.30.0 ``` ### Technical Analysis The dependency file specifies only minimum versions. A future installation may therefore resolve to any later release available from the configured package index. No lockfile or package hashes are provided to establish a reproducible, integrity-verified dependency set. The package names correspond to expected public packages, and the audit found no evidence of typosquatting, dependency confusion, or a malicious package source. The risk arises from accepting future unreviewed releases and from non-reproducible installation behavior. ### Attack Path 1. A user follows the documented dependency installation process. 2. The package resolver selects the newest versions satisfying the open-ended constraints. 3. A compromised, malicious, or unexpectedly incompatible future release is downloaded. 4. Package installation or runtime import executes that release under the user's privileges. ### Impact Assessment If an accepted dependency release is compromised, it may execute with the same privileges as the Skill and access workflow data, files, environment variables, and network resources. Absent an upstream compromise, the more likely impact is unexpected behavior or breakage caused by incompatible future versions. No current malicious dependency was confirmed. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (74)

Dangerous chain: exec() wrapping compile

Critical
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

This executes attacker-controlled Python code with exec(), which is inherently dangerous unless the sandbox is extremely robust. In this file the sandbox is not robust: it exposes file I/O, reflective builtins, and no real timeout, so untrusted workflow code can perform arbitrary local actions within the agent process.

Content

Scanner excerpt · scripts/engine/sandbox.py (reported line 117)May include surrounding context.

python
old_stdout = sys.stdout
    try:
        sys.stdout = captured
        exec(compile(code, "<openclaw-workflow-sandbox>", "exec"), namespace)
        sys.stdout = old_stdout

        # 优先使用 ctx_export() 的值,其次检查 namespace 中的 result 变量

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The workflow engine includes a code-evaluation capability via inline Python and indicates access to normal Python functionality, including file access and imports, without declaring equivalent permissions in the skill contract. This materially changes the trust model: a 'workflow' can become arbitrary code execution with filesystem access, enabling data theft, persistence, or local tampering.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The workflow engine includes a code-evaluation capability via inline Python and indicates access to normal Python functionality, including file access and imports, without declaring equivalent permissions in the skill contract. This materially changes the trust model: a 'workflow' can become arbitrary code execution with filesystem access, enabling data theft, persistence, or local tampering.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The workflow engine includes a code-evaluation capability via inline Python and indicates access to normal Python functionality, including file access and imports, without declaring equivalent permissions in the skill contract. This materially changes the trust model: a 'workflow' can become arbitrary code execution with filesystem access, enabling data theft, persistence, or local tampering.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `SKILL.md`:触发条件与使用说明

eval() call detected

High
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The condition evaluator passes attacker-controlled workflow expressions into Python eval(). Although builtins is restricted, the local namespace contains workflow globals, scopes, and step outputs, and Python expression evaluation still greatly expands the attack surface beyond simple deterministic branching. In a workflow engine, untrusted or semi-trusted YAML can turn conditions into code-like execution, enabling sandbox bypass attempts, denial of service, and unintended access to object internals.

Content

Scanner excerpt · scripts/engine/context.py (reported line 203)May include surrounding context.

python
}

        try:
            return bool(eval(resolved_str, {"__builtins__": safe_builtins}, namespace))
        except Exception:
            return False

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring says interactions no longer fork subprocesses, but the implementation still invokes subprocesses for script execution and message delivery. This mismatch can mislead reviewers and users about the actual trust boundary and execution risk, increasing the chance that dangerous functionality is enabled without proper scrutiny.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script node provides arbitrary shell and inline Python execution, which is far beyond a normal workflow-control function and effectively grants remote code execution to workflow definitions. Because commands and inline code are template-resolved from context, a malicious workflow can execute host commands, read files, and chain with network nodes for exfiltration.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This is direct tool-parameter abuse: workflow-controlled input becomes a shell command executed on the host. Because the tool accepts broad free-form parameters and uses shell=True, an attacker can craft commands to execute arbitrary programs, pivot to file access, and combine with HTTP/message nodes for exfiltration.

Content

Scanner excerpt · scripts/engine/nodes.py (reported line 76)May include surrounding context.

python
cwd = ctx.resolve(step.get("cwd")) if step.get("cwd") else None

    try:
        result = subprocess.run(
            command,
            shell=True,
            capture_output=True,

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
98% confidence
Finding

The script node passes the full host os.environ into executed commands, along with workflow-provided overrides. This exposes secrets such as API keys, tokens, and credentials to any script/command run by a workflow, making exfiltration straightforward once arbitrary execution is available.

Content

Scanner excerpt · scripts/engine/nodes.py (reported line 83)May include surrounding context.

python
text=True,
            timeout=timeout,
            cwd=cwd,
            env={**os.environ, **{k: str(v) for k, v in (step.get("env") or {}).items()}},
        )

        stdout = result.stdout.strip()

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The module advertises itself as a safe sandbox, but SAFE_BUILTINS includes open, allowing untrusted code to read and write arbitrary files accessible to the agent process. In a workflow engine, that can expose secrets, modify configs, overwrite data, or tamper with downstream execution state.

Content

No source excerpt is available for this finding.

exec() call detected

High
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The exec() call runs inline code from YAML workflows, turning workflow authors into code execution principals inside the application. In an agent system, this is especially dangerous because workflows may be user-supplied or remotely distributed, enabling local file access, denial of service, and possible sandbox escapes through Python introspection.

Content

Scanner excerpt · scripts/engine/sandbox.py (reported line 117)May include surrounding context.

python
old_stdout = sys.stdout
    try:
        sys.stdout = captured
        exec(compile(code, "<openclaw-workflow-sandbox>", "exec"), namespace)
        sys.stdout = old_stdout

        # 优先使用 ctx_export() 的值,其次检查 namespace 中的 result 变量

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · scripts/openclaw_workflow.py (reported line 141)May include surrounding context.

python
return 1

    port = getattr(args, 'port', 8501)
    os.execvp("streamlit", ["streamlit", "run", dashboard_path, "--server.port", str(port)])


def main():

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly advertises high-risk capabilities such as shell/Python script execution, HTTP requests, agent/subagent invocation, and messaging, but provides no warning about system modification, external network access, or possible data exfiltration. In a workflow engine context, this omission can cause users to treat the skill as routine automation rather than a powerful executor, increasing the chance of unsafe deployment or execution of untrusted YAML workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README advertises capabilities to execute shell/Python scripts, make HTTP requests, invoke agents/subagents, and send messages, but provides no visible warning that workflows may affect the local system, external services, or user data. In an agent-skill context, this omission is dangerous because users may run untrusted YAML workflows believing them to be routine automation, leading to command execution, network exfiltration, or unintended outbound communications.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill exposes powerful capabilities—shell execution, network access, file I/O, and environment-variable access—yet declares no explicit permission or tool scope. In a workflow engine that executes user-supplied YAML, this creates an overly broad execution surface and prevents operators from constraining dangerous actions before use.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The top-level description forces a specific language/locale in the skill’s natural-language interface content, and the rest of the file continues in Chinese. There is no indication that the skill is region-specific or that users may opt into another language, which conflicts with the stated policy against forcing a language without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation normalizes shell execution, network requests, code execution, and message sending but gives no warning that workflows may transmit data externally or cause real-world side effects. This omission increases the likelihood of unsafe use, especially because the skill is designed for automation where sensitive inputs may flow through multiple nodes.

Content

No source excerpt is available for this finding.

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 91)May include surrounding context.

md
steps:
  - id: fetch
    type: script
    command: "curl -s https://api.example.com/data"

  - id: analyze
    type: llm

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 351)May include surrounding context.

md
steps:
  - id: fetch
    type: script
    command: "curl -s https://api.example.com/data"

  - id: analyze
    type: llm

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 528)May include surrounding context.

md
steps:
  - id: fetch
    type: script
    command: "curl -s https://api.example.com/data"

  - id: analyze
    type: llm

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation advertises direct environment-variable interpolation without warning that secrets such as API keys, tokens, and credentials may be injected into prompts, logs, HTTP requests, or messages. In an orchestration engine with multiple outbound channels, this creates a practical secret-exfiltration risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This example workflow includes a script step that executes a shell command (date), which demonstrates arbitrary command execution capability inside a workflow example. Even though the specific command is harmless, normalizing script execution in a basic example increases the chance that users will copy the pattern for more powerful commands, expanding the attack surface beyond pure workflow control.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The workflow example demonstrates direct access to environment variables via {{env.HOME}}, which teaches and legitimizes reading process environment data from workflows. In real deployments, environment access can expose secrets, tokens, internal paths, or system metadata, especially if users generalize this pattern to other variables beyond HOME.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This YAML skill uses Chinese for the title, description, step names, and messages, which imposes a specific language on users. The file does not indicate that Chinese is optional, user-selected, or required for a region-specific purpose, so it violates the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/engine/context.py:203