Back to skill

Security audit

Fast Response Optimizer

Security checks for vulnerabilities and agentic risk

Overview

This skill is a response-speed optimizer, but it also persists sensitive agent memory files and exposes an unsafe shell-command helper without enough scoping or controls.

Review before installing. This skill may improve speed, but it can copy sensitive agent and user memory files into a predictable plaintext cache and includes an exported arbitrary command executor. Install only in a trusted, sandboxed workspace after accepting that data persistence, or after removing the shell executor and narrowing/protecting the cache.

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
scripts/cache-manager.js:8
Finding
Sensitive Agent State Persisted in a Predictable Plaintext Cache<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cache-manager.js:8-68` **Vulnerability Type**: Plaintext storage of sensitive Agent state **Risk Level**: Medium ### Vulnerable Code ```javascript const WORKSPACE = process.env.OPENCLAW_WORKSPACE || process.cwd(); const CACHE_DIR = path.join(WORKSPACE, 'cache'); const CACHE_FILE = path.join(CACHE_DIR, 'memory-cache.json'); const LAST_REFRESH_FILE = path.join(CACHE_DIR, '.last-refresh'); const LAST_MESSAGE_FILE = path.join(CACHE_DIR, '.last-message'); ``` ```javascript function loadCache() { console.log('🔄 加载记忆文件到缓存...\n'); // 确保缓存目录存在 initCache(); const cache = { timestamp: Date.now(), files: {} }; // 核心记忆文件 const files = { 'SOUL.md': path.join(WORKSPACE, 'SOUL.md'), 'USER.md': path.join(WORKSPACE, 'USER.md'), 'MEMORY.md': path.join(WORKSPACE, 'MEMORY.md'), 'AGENTS.md': path.join(WORKSPACE, 'AGENTS.md'), 'SESSION-STATE.md': path.join(WORKSPACE, 'SESSION-STATE.md'), 'HEARTBEAT.md': path.join(WORKSPACE, 'HEARTBEAT.md'), 'WORKING.md': path.join(WORKSPACE, 'WORKING.md') }; for (const [name, filePath] of Object.entries(files)) { const content = readFileSafe(filePath); if (content) { cache.files[name] = { content: content.substring(0, 5000), // 限制大小 size: content.length, mtime: fs.statSync(filePath).mtime.getTime() }; console.log(`✅ 缓存: ${name} (${content.length} 字符)`); } else { console.log(`⚠️ 跳过: ${name} (不存在)`); } } // 保存缓存 fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2)); fs.writeFileSync(LAST_REFRESH_FILE, Date.now().toString()); console.log(`\n✅ 缓存已保存: ${CACHE_FILE}`); console.log(`📊 共缓存 ${Object.keys(cache.files).length} 个文件`); return cache; } ``` ### Technical Analysis The cache manager collects up to 5,000 characters from each of several potentially sensitive OpenClaw files, including user data, long-term memory, system instruct ...[truncated 2249 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Adopt a default-deny cache policy and require an explicit allowlist of files that are safe and necessary to cache. 2. Do not persist `USER.md`, `MEMORY.md`, `SOUL.md`, `AGENTS.md`, or session-state files unless the user explicitly enables that behavior. 3. Prefer an in-memory cache so sensitive content is removed when the process exits. 4. If disk persistence is required, create the cache directory with mode `0700` and the cache file with mode `0600`, for example: ```javascript fs.mkdirSync(CACHE_DIR, { recursive: true, mode: 0o700 }); fs.writeFileSync(CACHE_FILE, JSON.stringify(cache), { encoding: 'utf8', mode: 0o600 }); ``` 5. Validate existing cache and directory ownership and permissions before reading or overwriting them. 6. Minimize cached content by storing only required derived metadata rather than raw file contents. 7. Define a retention period and securely delete stale cache files. 8. Clearly document the actual cache location and the categories of information copied into it. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/parallel-executor.js:95
Finding
Shell Command Injection Through Exported Parallel Command Executor<![CDATA[ ## Vulnerability Details **File Location**: `scripts/parallel-executor.js:95-111` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```javascript async function parallelExecCommands(commands) { const { exec } = require('child_process'); const util = require('util'); const execPromise = util.promisify(exec); const tasks = commands.map(cmd => ({ name: cmd, fn: async () => { try { const { stdout, stderr } = await execPromise(cmd, { timeout: 30000 }); return { stdout, stderr }; } catch (e) { return { error: e.message, code: e.code }; } } })); return parallelExecute(tasks); } ``` The function is exported at `scripts/parallel-executor.js:114-119`: ```javascript module.exports = { parallelExecute, parallelExecuteWithTimeout, parallelReadFiles, parallelExecCommands }; ``` ### Technical Analysis `parallelExecCommands()` accepts an array of command strings and passes every string directly to `child_process.exec()`. In Node.js, `exec()` runs the supplied text through a shell. Consequently, shell metacharacters, command substitutions, pipelines, redirections, and additional commands are interpreted rather than treated as literal arguments. The function implements no executable allowlist, argument validation, shell metacharacter rejection, authorization check, working-directory restriction, or privilege reduction. Exporting the function makes it available to other skill or OpenClaw components. The current project does not contain a direct call to `parallelExecCommands()`, so exploitation depends on another caller passing attacker-controlled or insufficiently validated command text. If that occurs, the function provides a direct command-injection sink. ### Attack Path 1. Another Agent component or integration imports `scripts/parallel-executor.js`. 2. That component constructs the `commands` array using user-controlled task text, model-genera ...[truncated 1425 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `parallelExecCommands()` if arbitrary command execution is not essential to the skill's documented purpose. 2. Do not pass user-controlled or model-generated text to a shell. 3. Replace `exec()` with `execFile()` or `spawn()` using a fixed executable and a separate argument array: ```javascript const { execFile } = require('child_process'); const { promisify } = require('util'); const execFilePromise = promisify(execFile); const ALLOWED_COMMANDS = new Set(['git', 'node']); async function runCommand(executable, args) { if (!ALLOWED_COMMANDS.has(executable)) { throw new Error('Command is not allowed'); } if (!Array.isArray(args) || !args.every(arg => typeof arg === 'string')) { throw new Error('Invalid command arguments'); } return execFilePromise(executable, args, { timeout: 30000, shell: false }); } ``` 4. Use a strict allowlist for executables and supported subcommands rather than a blocklist of dangerous characters. 5. Require explicit user authorization before executing commands with security-sensitive effects. 6. Run permitted commands under a dedicated least-privileged account or sandbox with restricted filesystem and network access. 7. Set explicit limits for output size, execution time, concurrency, environment variables, and working directory. 8. Record security-relevant command requests without logging secrets or sensitive command output. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The skill description does not clearly disclose all operational behavior, including startup/bootstrap execution via the documented bootstrap command. Description-behavior mismatches are dangerous because operators may trust the declared purpose while overlooking automatic initialization or side effects that run outside expected user-triggered actions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill description does not clearly disclose all operational behavior, including startup/bootstrap execution via the documented bootstrap command. Description-behavior mismatches are dangerous because operators may trust the declared purpose while overlooking automatic initialization or side effects that run outside expected user-triggered actions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill description does not clearly disclose all operational behavior, including startup/bootstrap execution via the documented bootstrap command. Description-behavior mismatches are dangerous because operators may trust the declared purpose while overlooking automatic initialization or side effects that run outside expected user-triggered actions.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The module exposes `parallelExecCommands(commands)`, which executes arbitrary shell commands via `child_process.exec` and runs them in parallel. In a skill whose stated purpose is response-speed optimization, this materially expands capability into arbitrary subprocess execution, creating command-injection and remote code execution risk if any caller passes user-influenced input.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill declares no explicit tool scope or permissions, yet its content describes code execution and cache-management behavior that implies environment and filesystem access. Missing scope declarations make it harder to review, constrain, and safely sandbox the skill, increasing the risk of unintended capability use.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill proposes persistent caching of user profile and memory summary data without notice, retention limits, or privacy controls. Persisting conversational state in files can expose sensitive personal or behavioral information if accessed by other skills, users, or processes, especially when refreshed automatically.

Vague Triggers

Medium
Confidence
95% confidence
Finding
An auto-trigger that runs on every message without scope constraints can cause pervasive, hard-to-audit behavior and may process sensitive conversations unnecessarily. In this skill, that risk is amplified by background execution and cache refresh logic, which could repeatedly touch files or state without clear user intent.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This JavaScript file contains user-facing natural-language strings and comments entirely in Chinese, including startup and error messages. The file does not offer any language choice or explain a justified region-specific requirement, which creates a locale policy concern under the rule for natural-language policy violations.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documentation describes periodic refresh and persistent storage of user_profile, memory_summary, and related state files, but does not clearly disclose this persistence to the user or define retention and protection controls. This is risky because user-related data and conversation-derived summaries may be stored automatically, expanding privacy exposure if accessed, retained too long, or used without informed consent.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill declares an automatic trigger on every message, which can cause it to run across nearly all conversations without clear scoping or user opt-in. In a skill that performs caching and background processing, this broad trigger increases the chance of unnecessary data handling, unintended persistence, and surprise execution outside the user’s expectations.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code includes natural-language descriptions and console output in Chinese, indicating the skill effectively forces a specific language for users and operators. The file does not provide any opt-in, fallback language, or justification that it is intentionally limited to a Chinese-speaking context.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The code performs parallel subprocess execution without any guardrails or warning to callers about the risks of running shell commands. Because `exec` invokes a shell, metacharacters and concatenated input can trigger unintended commands, and parallelism can amplify damage by executing multiple harmful operations at once.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
SQP-3 适用于所有文件类型。该技能说明整体强制以中文描述使用方式和规则,未见提供多语言选项、用户选择机制或明确说明这是仅面向中文区域的版本,存在语言/locale 策略上的潜在问题。

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The file’s human-facing comments and runtime log/error strings are consistently in Chinese, including status and timeout messages. This imposes a specific language/locale without any indication of user opt-in or documented justification, which matches the language-policy concern for natural-language behavior.

Static analysis

No suspicious patterns detected.