Back to skill

Security audit

feishu-process-feedback

Security checks for vulnerabilities and agentic risk

Overview

This Feishu task bot is mostly a coherent scaffold, but its task text can be passed into shell commands and retained in logs, which makes it unsafe to install without review.

Do not install this version for a real Feishu workspace until the shell-command construction is replaced with shell-free argument passing, raw task logging is removed or redacted, triggers are restricted to explicit authorized invocations, and the documentation is corrected to state which features are implemented versus placeholders.

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

Error
Location
scripts/process_task.js:79
Finding
Shell Command Injection Through Attacker-Controlled Feishu Task Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/process_task.js:79-87` **Additional Data-Flow Locations**: `scripts/process_task.js:223-229`, `scripts/process_task.js:240`, `scripts/process_task.js:256` **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable Code ```javascript async function sendFeedback(message, retryCount = 0) { try { // Escape special characters const escaped = message .replace(/\\/g, '\\\\') .replace(/"/g, '\\"') .replace(/\n/g, '\\n') .replace(/\r/g, ''); const cmd = `openclaw message send --channel feishu --message "${escaped}"`; await execAsync(cmd); ``` Attacker-controlled task content reaches this command-execution sink through feedback construction: ```javascript await sendFeedback( `📋 Task received, processing started...\n` + `Task ID: #${taskId}\n` + `Type: ${strategy.icon} ${parsed.type}\n` + `Total subtasks: ${total}\n` + `Main task: ${parsed.mainTask.substring(0, 60)}${parsed.mainTask.length > 60 ? '...' : ''}` ); ``` ```javascript const preview = subtask.replace(/^[\d\-\*•]+[\.\)]\s*/, '').substring(0, 50); ``` ```javascript await sendFeedback(`✅ Completed ${progress}% - ${preview}...`); ``` ### Technical Analysis The task processor receives Feishu task text through `process.argv[2]`. Portions of that text are subsequently included in progress messages and passed to `sendFeedback()`. `sendFeedback()` constructs a command string and executes it with `execAsync()`. Node.js `exec()` invokes a system shell. The implemented escaping only handles backslashes, double quotes, newlines, and carriage returns. It does not safely neutralize shell expansion features that remain active inside double-quoted shell strings, including command substitution using `$(...)` or backticks. Consequently, task text is interpreted partly as shell syntax rather than exclusively as the value of the `--message` argument. This is a direct command-i ...[truncated 1878 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not construct shell command strings from message content. 2. Replace `exec()` with `execFile()` or `spawn()` and pass every argument as a separate array element. This avoids shell parsing: ```javascript const { execFile } = require('child_process'); const { promisify } = require('util'); const execFileAsync = promisify(execFile); async function sendFeedback(message, retryCount = 0) { try { await execFileAsync('openclaw', [ 'message', 'send', '--channel', 'feishu', '--message', message ]); log('info', 'Feedback sent', { messageLength: message.length }); return true; } catch (error) { if (retryCount < CONFIG.maxRetries) { await sleep(CONFIG.retryDelay * (retryCount + 1)); return sendFeedback(message, retryCount + 1); } log('error', 'Feedback failed after maximum retries', { error: error.message }); return false; } } ``` 3. Apply the same shell-free invocation pattern to `scripts/listener.js:123-126`. 4. Do not rely on custom shell escaping as a security control. Correct escaping varies by shell and platform and is unnecessary when arguments are passed without a shell. 5. Add regression tests containing quotes, backticks, dollar signs, command-substitution syntax, semicolons, newlines, and platform-specific metacharacters. Verify they are transmitted literally and never executed. 6. Run the listener under a dedicated, unprivileged operating-system account with narrowly scoped filesystem and credential access to limit the consequences of any future execution flaw. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/process_task.js:58
Finding
Sensitive Task Content Is Persisted in Plaintext Logs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/process_task.js:58-66` **Additional Data-Flow Location**: `scripts/process_task.js:333-336` **Vulnerability Type**: Plaintext storage and excessive logging of potentially sensitive input **Risk Level**: Medium ### Vulnerable Code The logging function writes supplied data directly to a persistent local file: ```javascript function log(level, message, data = null) { const timestamp = new Date().toISOString(); const logEntry = `[${timestamp}] [Task #${taskId}] [${level.toUpperCase()}] ${message}${data ? ' ' + JSON.stringify(data) : ''}`; console.log(logEntry); try { fs.appendFileSync(CONFIG.logFile, logEntry + '\n'); } catch (error) { // Ignore log write errors } } ``` At startup, all task-processor arguments are joined and supplied to that logger: ```javascript log('info', 'Task processor started', { taskId, argv: process.argv.slice(2).join(' ') }); ``` The arguments contain the complete task text, task identifier, and message identifier. The listener also stores task previews and message identifiers in `.listener.log` at `scripts/listener.js:62-81` and `scripts/listener.js:199-204`. ### Technical Analysis Feishu task messages can contain business data, personal information, credentials, internal URLs, or other sensitive material. The task processor records the complete argument list in `.tasks.log`, including the unredacted task body. The log is created using `fs.appendFileSync()` without an explicit restrictive mode. Its effective permissions therefore depend on the process umask and deployment environment. The project also defines no retention period, rotation policy, maximum size, encryption, or automated deletion procedure. Although `.gitignore` excludes log files from ordinary Git commits, it does not protect files on the local system, in backups, in diagnostic bundles, or from accidental manual publication. Console logging can additionally expose the sam ...[truncated 1538 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove full command-line argument logging. Record only opaque operational metadata: ```javascript log('info', 'Task processor started', { taskId, messageId }); ``` 2. Do not log raw task bodies or subtask text. If diagnostics require context, use a non-reversible digest, character count, task type, or explicitly redacted summary. 3. Create log files with owner-only permissions, such as mode `0600`, and verify the parent directory is not accessible to unrelated users. 4. Implement log rotation, maximum file size, short retention periods, and secure deletion appropriate to the sensitivity of Feishu messages. 5. Ensure production console output does not contain task content, because service managers and centralized logging platforms may retain it independently. 6. Document what metadata is stored, where it is stored, and for how long. Obtain explicit administrator consent before enabling content-level diagnostic logging. 7. Consider passing task data over a private IPC channel or standard input rather than command-line arguments, since command-line values may also be observable through operating-system process inspection while the task is running. 8. Keep `.gitignore` protections, but do not treat them as an access-control or data-protection mechanism. ]]>
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description largely matches the intended architecture of the code: a background service with retry logic, persistence, process management, concurrency control, and feedback messaging. However, several central declared capabilities are only partially implemented or merely scaffolded. Most importantly, the listener does not actually fetch Feishu messages—getLatestMessage() is explicitly a TODO and always returns null—so the advertised core behavior of monitoring and automatically handling Feishu task messages does not currently occur. In addition, the claimed real-time progress reporting (including percentage and completion notifications) is not present in this file; only initial acknowledgment, queue warning, timeout, and shutdown messages are sent. The task parsing is also far simpler than the declared 'smart parsing' and 'task type recognition.' Because these gaps affect the primary advertised functionality rather than minor implementation details, this is a material description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
描述强调的是一个完整的飞书自动化后台技能,核心能力应包括监听消息、调度任务进程、并发控制和状态持久化。实际代码仅覆盖其中一部分:对已传入的任务文本做基础解析,按顺序循环处理,并发送飞书反馈消息与记录日志。该脚本更像“单个任务子处理器”,而不是描述中的完整后台监听与调度技能。虽然它确实包含进度反馈、基础任务分类、错误处理和重试,但缺失了声明中的关键主能力,且实际执行逻辑仍是模拟占位,因此描述与代码行为存在实质不匹配。

Vague Triggers

High
Confidence
97% confidence
Finding
The trigger keywords are extremely broad and overlap with normal conversation, making accidental task activation likely. In a continuously running background listener that may launch processing automatically, false triggers can cause unintended actions, message leakage, queue flooding, or abuse by anyone who can send crafted chat text.

Ae1

High
Category
analysis-evasion
Content
node scripts/listener.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/listener.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/listener.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/listener.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/listener.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/listener.js
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
编辑 `scripts/process_task.js` 中的 `executeSubtask()` 函数:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Intent-Code Divergence

High
Confidence
97% confidence
Finding
文件头部与类注释宣称该脚本会在后台监听飞书消息并创建处理进程,但实际 `getLatestMessage()` 明确写有 TODO,且当前实现仅记录“检查新消息”后直接返回 `null`。这不是单纯的实现细节缺失,而是文档所承诺的核心能力与代码当前行为相矛盾,导致技能实际上不会监听或处理任何飞书消息。

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README promotes continuous background listening, message parsing, state persistence, and progress feedback, but does not clearly warn users that the skill monitors messages and may store task content in logs or state files. In a messaging environment, this creates privacy and compliance risk because users may not realize their conversations are being watched, retained, and acted upon automatically.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The example trigger is a normal-language request ('帮我处理这个任务…') that closely overlaps with routine chat and work messages. In a skill designed to continuously listen to Feishu messages and automatically spawn processing jobs, this can cause accidental activation on benign conversations, leading to unintended task execution, data processing, or outbound actions such as report generation or email sending.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill describes behavior that requires network access and likely environment-based secrets, but it does not explicitly declare a tool/permission scope. That creates hidden capability risk: operators may install a background listener without clear visibility that it will poll external APIs and use credentials, weakening review and consent boundaries.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
文件中的名称、描述、示例反馈文本和使用说明均固定为中文,没有说明这是特定区域/组织限定技能,也没有提供用户语言选择。若组织要求避免无选择地强制单一语言,这构成语言/locale 策略风险。

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The description under-communicates that the skill continuously monitors messages and automatically sends status updates over external channels. Insufficient disclosure is dangerous because users or administrators may deploy it without understanding that it is effectively a persistent bot processing communication data in the background.

Context-Inappropriate Capability

Medium
Confidence
86% confidence
Finding
The extension guidance encourages implementers to add arbitrary task-processing logic, expanding the skill from message feedback into general-purpose execution. In a background, message-driven skill, that broadens the attack surface significantly because incoming chat content could become a trigger for higher-risk actions not constrained by the stated purpose.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
User-visible text and instructional comments throughout the file are written exclusively in Chinese, including status output and operational messages. There is no indication that the skill is region-specific or that users can opt into another language, which can violate language/locale policy requirements.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
User-controlled message content is interpolated into a shell command and executed through exec, with only double quotes and newlines escaped. Shell metacharacters such as backticks or command substitution syntax may still be interpreted by the shell, creating a command-injection path when feedback messages contain attacker-controlled text.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
Manifest描述该技能会识别任务类型、智能解析并在独立进程中自动处理任务,还支持错误重试、并发控制和状态持久化。这里的核心执行函数仅sleep后直接返回成功,注释还明确写明“应集成具体业务逻辑”,说明实际行为主要是发送反馈与伪造完成状态,而非真正处理任务。

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script sends task-derived content to an external messaging command and persists operational details to a local log without any minimization or consent controls. In a workflow processor, task text can easily contain sensitive business data, credentials, or personal information, so routine forwarding and persistence creates a real confidentiality risk.

Ssd 3

Medium
Confidence
95% confidence
Finding
The code logs `taskPreview` and the full CLI argument string (`argv`), both of which may include sensitive task text or identifiers supplied by users. Because these values are written to `.tasks.log` and also surfaced in status flows, anyone with log access or downstream message visibility may learn confidential contents that were never meant to be retained or shared.

Ssd 3

Medium
Confidence
96% confidence
Finding
The script repeatedly includes subtask previews and raw error text in outbound progress messages. In this skill context, progress updates are automatic and frequent, so sensitive instructions, names, internal project details, or error-derived secrets can be broadcast through routine operational messaging without review.

Missing User Warnings

Low
Confidence
87% confidence
Finding
This markdown file contains a destructive operation (`rm -f .listener.log .tasks.log`) that deletes local files, but the surrounding instructions do not explicitly warn the user that files will be removed. Under the markdown criteria for SQP-2, skills should disclose behaviors that can affect user data or system state.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This markdown file contains user-facing instructions exclusively in Chinese, and there is no note that the language is optional or tailored to a specific audience. Under the policy rule, forcing a specific language without user opt-in can be a natural-language policy violation.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/listener.js:221

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/listener.js:25