Back to skill

Security audit

calender-memo

Security checks for vulnerabilities and agentic risk

Overview

This calendar skill should be reviewed because it can automatically send private schedule details through Feishu and uses unsafe shell command construction.

Install only if you are comfortable with calendar titles and times being sent through a configured Feishu/OpenClaw messaging channel. The publisher should replace shell `exec` with argument-based process execution, make external reminders opt-in, add disable controls, and clarify the push behavior in the main skill description before broad use.

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

Warning
Location
reminder.js:14
Finding
Latent OS Command Injection in Push Notification Construction## Vulnerability Details **File Location**: `reminder.js`, lines 14-30 **Vulnerability Type**: OS command injection through unsafe shell interpolation **Risk Level**: Medium ### Vulnerable Code ```javascript function sendPushNotification(messageText) { // Use the openclaw command to send a message through the Feishu channel // --channel selects the channel; --recipient current selects the current user const cmd = `openclaw message send --channel feishu --recipient current --text "${messageText.replace(/"/g, '\\"')}"`; exec(cmd, (error, stdout, stderr) => { if (error) { console.error(`Push failed: ${error.message}`); return; } if (stderr) { console.error(`Push stderr: ${stderr}`); return; } console.log(`Push succeeded: ${stdout}`); }); } ``` ### Technical Analysis `sendPushNotification()` incorporates `messageText` into a command string passed to `child_process.exec()`. The function escapes only double quotation marks. This does not neutralize shell substitutions that remain active inside double-quoted strings, including: - Command substitution using `$(command)` - Command substitution using backticks - Environment-variable expansion - Certain backslash and shell-specific expansion sequences Event titles originate from user messages in `SOUL.md` and are incorporated into reminder messages without validation: ```javascript const title = parts.slice(1).join(' '); ``` The resulting title is persisted in `MEMORY.md` and later included in `messageText`. For example, a title containing `$(touch /tmp/pwned)` would cause the shell to execute `touch /tmp/pwned` when the command string reaches `exec()`. The issue is latent in the artifact as provided because `reminder.js` currently defines `loadEvents()` as an empty placeholder: ```javascript function loadEvents() { /* ... */ } ``` It therefore returns `undefined`, and `checkRemi ...[truncated 2201 chars]
Remediation
## Remediation Suggestions 1. Replace `exec()` with `execFile()` or `spawn()` and pass every command argument separately, with shell processing explicitly disabled: ```javascript const { execFile } = require('child_process'); function sendPushNotification(messageText) { execFile( 'openclaw', [ 'message', 'send', '--channel', 'feishu', '--recipient', 'current', '--text', messageText ], { shell: false }, (error, stdout, stderr) => { if (error) { console.error(`Push failed: ${error.message}`); return; } if (stderr) { console.error(`Push stderr: ${stderr}`); } console.log(`Push succeeded: ${stdout}`); } ); } ``` 2. Do not attempt to make shell command construction safe through manual escaping. Correct escaping is platform- and shell-dependent and is unnecessary when argument-array APIs are used. 3. Validate event titles at ingestion: - Enforce a reasonable maximum length. - Reject control characters and null bytes. - Normalize unexpected Unicode control characters. - Treat validation as defense in depth rather than a replacement for eliminating the shell. 4. Implement `loadEvents()` securely and verify that the parsed value is an array before iterating over it. Reject malformed event records rather than silently forwarding their fields into privileged operations. 5. Run the skill under a dedicated, least-privileged operating-system account with restricted filesystem and credential access. 6. Add automated tests using titles containing `$(...)`, backticks, quotation marks, semicolons, newlines, and backslashes, and verify that none can trigger a secondary process.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared behavior is a local calendar/memo tool, but the finding indicates additional capabilities including external Feishu message delivery, minute-by-minute background polling, and system command execution via exec. That combination materially expands the trust boundary: user schedule data could be transmitted off-device and command execution introduces command-injection or abuse risks that are not disclosed by the skill description.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill is described as a local calendar/memo tool, but this module sends event data outward via Feishu push messages. That expands the trust boundary from local storage to external messaging and can leak sensitive schedule contents without clear user consent or manifest-level disclosure.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code constructs a shell command with user-influenced text and executes it via exec, which introduces command-injection risk and unnecessary shell exposure. Even though quotes are partially escaped, shell metacharacters such as backticks or $(...) can still be interpreted inside double quotes, allowing crafted event titles to trigger unintended command execution.

Vague Triggers

Medium
Confidence
95% confidence
Finding
L05-L07 将触发条件定义为“用户需要记录待办事项、安排日程、提醒自己未来的事情”,并列出“安排”“备忘”“计划”等宽泛关键词,这些表述覆盖大量普通对话场景。虽然文档提供了一些示例,但没有给出明确的限定触发短语或足够的排除条件,容易造成技能在非目标语境下被调用。

Missing User Warnings

Medium
Confidence
88% confidence
Finding
Persisting schedule data to a local file without sufficiently prominent disclosure creates a privacy risk because users may reveal sensitive appointments, reminders, or personal notes without realizing they are being stored. In a calendar context, stored entries can contain highly sensitive behavioral and business information, making lack of clear notice and consent more dangerous.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill formats output using the 'zh-CN' locale and all command phrases and responses are fixed in Chinese, with no indication that the user can choose another language or that the skill is intentionally region-specific. This creates a natural-language policy concern because the skill effectively forces a specific language/locale without opt-in.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill deletes persisted calendar items immediately based on a user-supplied index, with no confirmation step, undo flow, or secondary validation. In a conversational interface, ambiguous, accidental, or spoofed commands can easily trigger unintended data loss, especially because the data is stored locally and deletion is permanent.

Intent-Code Divergence

Medium
Confidence
79% confidence
Finding
The file header describes the module as a reminder component, but the implemented behavior is stronger: it proactively pushes messages out through Feishu using an external command. Given the manifest's local memo framing, this documentation understates and conflicts with the actual externally communicative behavior.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The module starts a background checker that can send pushes and persist reminder state without any visible confirmation, notice, or runtime consent in this file. In a calendar context, silent background delivery can expose private schedule details and surprise users with actions occurring outside their immediate interaction.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
文件中的名称、描述、触发条件和示例全部以中文固定呈现,且未说明是否支持其他语言或允许根据用户偏好切换语言。若组织要求技能不应在无用户选择的情况下强制特定语言,这种自然语言说明构成潜在的语言/locale 策略问题。

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The reminder message uses toLocaleString('zh-CN', ...) and surrounding comments/messages are written in Chinese, which indicates the skill is hard-coded to a specific language/locale. Under the policy, forcing a locale without user opt-in or clear justification is a natural-language policy violation.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
reminder.js:20