Back to skill

Security audit

TOKEN SOP

Security checks for vulnerabilities and agentic risk

Overview

This token-saving workflow cache has a coherent purpose, but it automatically runs and shares browser workflows with broad cloud and local authority that needs careful review before installation.

Review this skill before installing, especially in authenticated browsers, business apps, financial systems, admin consoles, or private/internal sites. It can replay workflows automatically, retrieve workflows from a cloud endpoint, and upload workflow context by default. Installation would be more appropriate only after cloud contribution is opt-in, remote workflows require trust and user approval, local storage settings are honored, matching is origin-bound, and privacy sanitization is strengthened.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
src/interceptor.ts:84
Finding

Automatic Retrieval and Execution of Untrusted Remote Workflows

Content
View full analysis
("cloud_endpoint"); const timeoutMs = config.get("timeout_ms"); const client = new CloudClient(cloudEndpoint, timeoutMs, logger); let matchResult: MatchResponse | null = null; try { matchResult = await client.match({ intent: parsed.normalized, url, dom_skeleton_hash: domHash, node_id: nodeId, }); } catch { logger.debug("[ClawMind] Cloud unreachable, passing through"); gateway.passthrough(); return; } if (!matchResult || !matchResult.hit || !matchResult.macro) { logger.info("[ClawMind] No macro match, passing through to OpenClaw"); gateway.passthrough(); return; } const macro = matchResult.macro; if (!lobster.validate(macro.lobster_workflow)) { logger.warn(`[ClawMind] Workflow validation failed for ${macro.macro_id}`); gateway.passthrough(); return; } let execResult: LobsterExecutionResult; try { execResult = await lobster.execute(macro.lobster_workflow); } catch (err) { // ... } ``` The remote response is obtained as follows: ```ts const { statusCode, body } = await request( `${this.endpoint}/v1/lobsters/match`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(req), headersTimeout: this.timeoutMs, bodyTimeout: this.timeoutMs, } ); if (statusCode !== 200) { this.logger.warn(`Cloud match returned ${statusCode}`); return null; } return (await body.json()) as MatchResponse; ``` ### Technical Analysis The Skill obtains a `lobster_workflow` from a configurable remote endpoint and executes it automatically. The payload contains executable command strings represented by `LobsterStep.command`. The only execution gate is `lobster.validate()`. Its implem ...[truncated 1884 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/interceptor.ts:183
Finding

Default Cloud Contribution Can Disclose Unsanitized Session and Browser Data

Content
View full analysis
("enabled") || !config.get("auto_contribute")) { return; } // ... const intent = history.intent; if (!intent) return; const url = await browser.getCurrentUrl(); const domHash = await browser.getDomSkeletonHash(); const nodeId = workspace.getNodeId(); // Compile the trace into a Lobster workflow const { workflow, argCount } = compileTrace(intent, history.actions); // ... const result = await client.contribute({ node_id: nodeId, intent, url, dom_skeleton_hash: domHash, lobster_workflow: workflow, session_id: sessionId, }); ``` The sanitizer processes only top-level values and passes non-string values through unchanged: ```ts for (const [key, value] of Object.entries(args)) { const lowerKey = key.toLowerCase(); if (SENSITIVE_FIELD_NAMES.has(lowerKey)) { const argName = lowerKey; const placeholder = `$LOBSTER_ARG_${argName.toUpperCase()}`; allExtracted.set(argName, { type: typeof value === "number" ? "number" : "string", placeholder, originalPattern: `field:${key}`, }); sanitized[key] = placeholder; continue; } if (typeof value === "string") { const { sanitized: cleanValue, extractedArgs } = sanitizeTrace(value); sanitized[key] = cleanValue; for (const [k, v] of extractedArgs) { allExtracted.set(k, v); } } else { sanitized[key] = value; } } ` ...[truncated 1988 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/trace-compiler.ts:89
Finding

Unescaped Action Arguments Are Embedded in Executable Workflow Commands

Content
View full analysis
): string { const argsStr = Object.entries(args) .map(([k, v]) => { if (typeof v === "string") return `${k}="${v}"`; return `${k}=${v}`; }) .join(" "); return `openclaw.invoke ${tool}.${action} ${argsStr}`.trim(); } ``` ### Technical Analysis The compiler constructs executable Lobster command text through direct string interpolation. Argument keys, string values, tool names, and action names are not escaped or validated for the syntax consumed by the Lobster command parser. A string containing quotes, backslashes, newlines, substitutions, or command separators can terminate its intended quoted context or alter how the command is parsed. Non-string objects are implicitly converted through JavaScript string interpolation and are not serialized using a defined safe format. The PII sanitizer used before this function performs redaction, not command-language escaping. It therefore does not prevent syntax injection. ### Attack Path 1. Attacker-controlled content enters a successful browser action's arguments. This can occur through page-derived selectors, text, URLs, or values recorded by the session trace. 2. The session completion hook calls `compileTrace()`. 3. `buildCommand()` inserts the value directly between double quotes without escaping it for the Lobster parser. 4. The malformed command is persisted locally and may also be uploaded to the cloud. 5. During a later local or remote replay, Lobster parses the injected syntax as part of the executable command. 6. The injected operation executes with the permissions granted to the workflow runtime. The exact injection syntax depends on Lobster's parser, which is outside the reviewed repository. Nevertheless, direct con ...[truncated 715 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/local-store.ts:96
Finding

Cross-Origin Workflow Replay Caused by URL-Blind Fuzzy Matching

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/interceptor.ts:55
Finding

Local Storage Security Configuration Is Ignored

Content
View full analysis
Remediation
View remediation
("local_store_enabled"), storageDir: config.get("local_store_dir"), }; ``` 2. Expand `~` safely to the current user's home directory and validate the resolved path. 3. When storage is disabled, skip lookup, saving, failure tracking, and initialization. 4. Create directories and files with restrictive permissions, such as owner-only access where supported. 5. Use atomic writes through a temporary file in the same directory followed by rename. 6. Reject symbolic-link traversal and verify that resolved files remain under the configured directory. 7. Provide a migration and deletion mechanism for data already written to the default directory. 8. Add configuration tests demonstrating that disabled storage produces no filesystem reads or writes and that custom directories are honored. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (31)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The failure-reporting path sends a domSnapshot to a remote feedback endpoint with no visible sanitization, redaction, or user warning. DOM snapshots can contain credentials, tokens, personal data, page content, and other sensitive context, making this a significant data-exfiltration and privacy risk if captured from real user sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The session completion hook automatically uploads a compiled workflow derived from user actions, along with intent, URL, DOM hash, node ID, and session ID, whenever auto_contribute is enabled, with no user-facing warning or approval shown here. Because workflows may encode sensitive business processes, page structure, navigation targets, and potentially secret-bearing actions, automatic contribution to a shared cloud service materially increases the risk of privacy leakage, cross-tenant data exposure, and unintended disclosure of proprietary automation traces.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: undici==7.24.4 — 12 advisory(ies): CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-13697 (undici vulnerable to cross-user information disclosure and parse-time crash via ); CVE-2026-16728 (undici vulnerable to downstream response desynchronization via retry interceptor) +9 more

High
Category
Supply Chain
Confidence
95% confidence
Finding

The lockfile pins the runtime dependency undici to version 7.24.4, and the supplied advisory set indicates this exact version is affected by multiple high-severity issues, including response queue poisoning, information disclosure, and response desynchronization. Because undici is an HTTP client library, vulnerabilities in it can directly affect network trust boundaries and may enable request/response mixups, data leakage between users, or denial of service when the skill communicates with remote services.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: undici==7.24.4 — 12 advisory(ies): CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-13697 (undici vulnerable to cross-user information disclosure and parse-time crash via ); CVE-2026-16728 (undici vulnerable to downstream response desynchronization via retry interceptor) +9 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

The package allows installation of an undici version identified as having multiple known advisories, including HTTP desynchronization, queue poisoning, and potential information disclosure issues. Because undici is an HTTP client library, a workflow-caching skill that communicates over the network could expose requests, responses, or cross-request boundaries if a vulnerable version is used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language content of the skill file appears to require Chinese comprehension, and there is no indication that users can select another language or that the skill is intentionally limited to a Chinese-speaking audience. This can violate language or locale policy when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill enables automatic cloud contribution by default while also describing local workflow storage, but it does not clearly warn users what data may be uploaded, when uploads occur, or how sensitive workflow contents are sanitized. In a skill that caches and reuses prior task data, this creates a real risk of unintended disclosure of prompts, outputs, secrets, or other sensitive operational context to a remote service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The client transmits contribution data, along with a configured nodeId, to a remote API without any visible consent, disclosure, or data-minimization controls in this code path. If the contributed payload contains sensitive or proprietary information, users or integrators may unknowingly exfiltrate data to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The match method sends the serialized req object to a remote endpoint via HTTP POST, but this file provides no confirmation prompt, user-facing notice, or explanatory comment/docstring about that data transmission. Because the same pattern appears in other methods as well, the code performs cloud submission of request contents without visible disclosure in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The contribute method POSTs JSON-serialized request data to /v1/lobsters/contribute, but the code includes no prompt, user-visible notice, or inline documentation warning that local data will be transmitted externally. This is a safety-relevant network operation and lacks any visible disclosure within the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This JavaScript file is a code file, so SQP-2 applies. The doc comment states that the skill "fires on every user intent" and "queries cloud" and later "contributes new workflows," which implies networked handling of user/session data, but this file shows no confirmation, user-facing logging, or warning about that behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The comments describe automatically contributing successful session outputs to a cloud service after execution, with no indication of user notice, consent, or data minimization. Because session data and generated workflows may contain credentials, sensitive prompts, internal URLs, or proprietary actions, silent upload creates a real privacy and data-exfiltration risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The interface states that a completed session trace is compiled into a workflow and then saved locally and contributed to the cloud, again without any visible consent boundary or user-facing disclosure. Session traces are especially sensitive because they can encode user actions, targets, prompts, and possibly authentication material, so automatic sharing materially increases exposure and cross-tenant leakage risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The interceptor sends the normalized user intent, current URL, DOM skeleton hash, and node identifier to a cloud service during intent matching without any evidence of explicit user notice, consent, or data minimization in this file. In an agent/browser-automation context, those fields can reveal sensitive browsing activity, internal app structure, and tenant-identifying metadata, creating a privacy and confidentiality risk even if the feature is product-intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code persists workflow data, including intent and URL, to local JSON files and later supports deletion, but provides no confirmation prompt, logging, or user-facing notice around those filesystem changes. For a code file, safety-relevant file writes/deletions should have some visible disclosure unless clearly covered elsewhere, and no such warning is present in this file.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file advertises itself as the primary privacy gate that strips all identifiable information before data leaves the node, but the implementation only iterates over top-level entries in args and only sanitizes direct string values. Nested objects, arrays, and deeply embedded strings are passed through unchanged, so PII inside structured action arguments can be exfiltrated despite the privacy guarantee.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The package description is written entirely in Chinese and provides no indication that users can choose another language or locale. Under the policy, forcing a specific language without opt-in or documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest enables automatic contribution of successful workflows to a cloud endpoint by default, but it does not indicate any consent flow, warning, or scoping of what workflow data may be transmitted. Because workflows can contain sensitive prompts, outputs, and task context, silent default upload creates a real privacy and data exfiltration risk, especially given the skill also requests network and session-related permissions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The cloud match request sends normalized user intent, current URL, DOM skeleton hash, and node identifier to a remote service, and the contribution path later uploads full workflows and session-linked metadata. In an agent/browser automation context, those fields can reveal sensitive browsing targets, business context, internal application structure, and potentially user behavior without explicit consent or clear notice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code persists workflow records, including intent, URL, and workflow contents, to a local JSON file via fs.writeFileSync, but there is no confirmation prompt, logging, or user-facing notice around the data write. Although comments describe the behavior for developers, they do not disclose to end users that potentially sensitive workflow and URL data will be stored locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The deleteLocalWorkflow function irreversibly removes a local JSON file using fs.unlinkSync, but provides no confirmation prompt, logging, or user-facing disclosure. For a destructive file operation, the absence of any visible warning increases the chance of silent data loss.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module advertises itself as the primary privacy gate that strips all identifiable information before any data leaves the node, but the implementation only performs narrow regex matching and exact field-name checks on top-level keys. This mismatch can cause operators or downstream components to trust the sanitizer and transmit unsanitized PII, secrets, or nested sensitive data, creating a real data-leak risk rather than merely a documentation issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The reportFailure method sends JSON request data to a cloud endpoint using HTTP PUT, but there is no confirmation, visible user notice, or explanatory documentation in this file. Even though this appears operationally useful, it still transmits data externally without an explicit warning.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file's natural-language comments are written in Chinese only, which imposes a specific language choice without offering alternatives or documenting a justified locale-specific scope. This matches the policy category for language or locale constraints in natural-language content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The descriptive comments and docstrings are written in Chinese, which imposes a specific language in the skill's natural-language content without any indication of user opt-in or locale justification. Under the language/locale policy rule, forcing a single language can be a policy concern when no choice or rationale is provided.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The module reads process.env.HOME to derive a default persistence directory under the user's home folder, which affects where user-related workflow data is stored. There is no user-facing notice, log, or explicit warning in this file explaining that data will be persisted in a hidden directory beneath the home directory.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.