Back to skill

Security audit

claw-lark Patches

Security checks for vulnerabilities and agentic risk

Overview

This skill openly patches a local Lark plugin, but its auto-apply script makes persistent installed-code changes and unsafely embeds environment values into JavaScript source.

Review the patch script before installing, run it only from a clean environment, set BOT_OPEN_ID and BOT_NAME to simple expected values, and keep a backup or versioned copy of the claw-lark dist files so the plugin can be restored if the patch breaks or captures unsafe input.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apply-patches.sh:145
Finding
JavaScript Source Injection Through Unescaped Environment Variables<![CDATA[ ## Vulnerability Details **File Location**: `scripts/apply-patches.sh`, lines 39-40 and 145-146 **Vulnerability Type**: JavaScript code injection through unsafe source-code generation **Risk Level**: High ### Vulnerable Code ```javascript const BOT_OPEN_ID = process.env.BOT_OPEN_ID || 'YOUR_BOT_OPEN_ID'; const BOT_NAME = process.env.BOT_NAME || 'YOUR_BOT_NAME'; ``` The environment-derived values are subsequently interpolated directly into JavaScript source code: ```javascript const BOT_OPEN_ID = "${BOT_OPEN_ID}"; const BOT_NAME = "${BOT_NAME}"; ``` ### Technical Analysis The script reads `BOT_OPEN_ID` and `BOT_NAME` from the invoking process environment and embeds them into replacement text that is written to the installed `monitor.js` file. The values are inserted inside JavaScript string literals without escaping or serialization. An attacker-controlled value containing a double quote, newline, backslash, or JavaScript syntax can terminate the intended string literal and inject additional statements into `monitor.js`. The shell's quoted heredoc prevents shell expansion, but it does not protect the later JavaScript template-literal interpolation performed by the Node.js patching program. This is a persistent source-injection issue rather than only a malformed-configuration issue: the generated code is saved to the installed claw-lark plugin and is subsequently loaded when the gateway restarts. ### Attack Path 1. An attacker gains influence over the environment used to invoke the patch script, such as through a wrapper script, compromised deployment configuration, CI variable, shell initialization file, or misleading setup instructions. 2. The attacker supplies a crafted `BOT_OPEN_ID` or `BOT_NAME` value containing a closing quote followed by JavaScript statements. 3. A user executes: ```bash bash scripts/apply-patches.sh ``` 4. The Node.js patching logic interpolates the crafted value into the replacement source without escaping i ...[truncated 1262 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Serialize all environment-derived values before embedding them in generated JavaScript. For example: ```javascript const serializedBotOpenId = JSON.stringify(BOT_OPEN_ID); const serializedBotName = JSON.stringify(BOT_NAME); ``` Then construct the replacement source using those serialized values without adding another pair of quotes: ```javascript const replacement = `const BOT_OPEN_ID = ${serializedBotOpenId}; const BOT_NAME = ${serializedBotName};`; ``` Additional hardening should include: 1. Validate `BOT_OPEN_ID` against the expected Lark identifier format before patching, such as a strict `ou_`-prefixed allowlist pattern. 2. Apply a reasonable maximum length to both variables. 3. Reject control characters and unexpected line breaks. 4. Prefer reading bot identity from runtime configuration rather than generating source code from environment input. 5. Write the patched file atomically and validate its JavaScript syntax before replacing the installed file. 6. Abort the operation when validation or an expected patch fails instead of leaving a partially patched plugin. 7. Add tests covering quotes, backslashes, template-literal markers, Unicode, and newline characters in both configuration values. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill includes operational steps that rely on environment variables such as BOT_OPEN_ID and BOT_NAME, but it declares no explicit tool scope or permissions metadata. That mismatch is risky because it obscures the skill's runtime assumptions and can lead an agent or operator to expose environment data or execute the skill with broader capabilities than intended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill tells the user to run an auto-apply shell script immediately, while the document itself states that it patches compiled plugin dist files directly. Encouraging execution of a modification script without an inline warning, review guidance, backup steps, or integrity checks is dangerous because it can cause silent code changes in production-facing plugin files and normalize running unreviewed scripts.

Session Persistence

Medium
Category
Rogue Agent
Content
- ✅ Exact match `m.id.open_id === BOT_OPEN_ID`

### Thread Reply
- ❌ `client.im.message.create()` + `root_id` → only associates, doesn't create thread
- ❌ `thread_id` as `receive_id` → 400 error
- ✅ `client.im.message.reply()` + `reply_in_thread: true` → creates thread
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
Line L26 specifies the bot name in Chinese without any indication that language choice is configurable or user-selected. This can violate language/locale policy expectations when a skill implicitly fixes output or identity to a specific language without opt-in.

Static analysis

No suspicious patterns detected.