可疑 — 风险评分 45/100
上次扫描:1 天前 重新扫描
45 /100
calendar_memo
本地日程记事本 - 添加、查看、完成和删除待办事项和日程安排
Skill executes undeclared shell commands via child_process.exec and runs persistent background timers without proper documentation disclosure.
技能名称calendar_memo
分析耗时46.9s
引擎pi
谨慎使用
Add explicit documentation about shell execution, background processes, and required network permissions. Consider using a safer IPC mechanism instead of exec() for inter-process communication.

攻击链 4 步

入口 Skill loaded via SKILL.md documentation describing only local scheduling features
SKILL.md:1
提权 onStart() triggers startReminderChecker() which creates persistent setInterval
SOUL.md:44
提权 Every 60 seconds, checkReminders() builds command string with user-controlled title
reminder.js:35
影响 exec() executes 'openclaw message send' through system shell with potentially unsanitized input
reminder.js:18

安全发现 4 项

严重性 安全发现 位置
高危
Undeclared shell command execution 权限提升
The skill uses child_process.exec() to execute 'openclaw message send' but SKILL.md only mentions '飞书等通道' (Feishu channels) without explaining the shell execution mechanism. Users cannot make informed decisions about allowing this skill.
exec(cmd, (error, stdout, stderr) => {...})
→ Document shell:WRITE permission and explain that the skill executes external CLI commands for notifications.
reminder.js:18
中危
Shell command injection risk in notification function 代码执行
The sendPushNotification function builds a shell command by interpolating user-controlled event title into a command string. While only double quotes are escaped, other shell metacharacters could potentially be dangerous if the message format changes.
const cmd = `openclaw message send --channel feishu --recipient current --text "${messageText.replace(/"/g, '\\"')}"`
→ Use an array-based exec() API or proper argument escaping via a library like shell-quote instead of string interpolation.
reminder.js:14
中危
Hidden background daemon without disclosure 持久化
The skill starts a setInterval timer that runs checkReminders() every 60 seconds. This creates a persistent background process that continues running until skill is explicitly stopped. SKILL.md does not mention this behavior.
intervalId = setInterval(() => { checkReminders(); }, 60 * 1000);
→ Document that the skill runs background checks and the interval frequency. Allow users to configure or disable reminder checking.
reminder.js:55
低危
Minor doc-to-code mismatch on filesystem permissions 文档欺骗
SKILL.md capability section mentions '读取和编辑MEMORY.md' (read and edit) but only declares filesystem:READ. The code writes to MEMORY.md using writeFileSync.
fs.writeFileSync(MEMORY_FILE, JSON.stringify(events, null, 2), 'utf8');
→ Update SKILL.md to declare filesystem:WRITE permission.
SOUL.md:13
资源类型声明权限推断权限状态证据
文件系统 READ WRITE ✓ 一致 reminder.js:3 - fs module available; SOUL.md:13 - fs.writeFileSync writes MEMORY…
命令执行 NONE WRITE ✗ 越权 reminder.js:4 - const { exec } = require('child_process'); reminder.js:18 - exec…
网络访问 NONE WRITE ✗ 越权 reminder.js:18 - exec runs 'openclaw message send --channel feishu' which sends …
环境变量 NONE NONE No direct environment variable access found

目录结构

4 文件 · 11.3 KB · 363 行
Markdown 3f · 279L JavaScript 1f · 84L
├─ 📝 MEMORY.md Markdown 1L · 2 B
├─ 📜 reminder.js JavaScript 84L · 2.3 KB
├─ 📝 SKILL.md Markdown 52L · 1.9 KB
└─ 📝 SOUL.md Markdown 226L · 7.1 KB

安全亮点

✓ No credential harvesting or sensitive data exfiltration detected
✓ No base64 encoding, eval(), or obfuscation techniques found
✓ No network requests to unknown external IPs
✓ Data stays local in MEMORY.md without transmission
✓ User input is processed through structured parsing rather than eval()