Back to skill

Security audit

Feishu Img Tool

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated Feishu image-sending purpose, but it includes unsafe command execution and dependency handling that warrant Review before installation.

Review carefully before installing. Avoid using this package with untrusted image paths, recipient IDs, or message text until the exec-based wrapper is replaced with execFile or spawn and arguments are passed without a shell. Prefer environment variables or a secret store for Feishu credentials; if using ~/.feishu-image/config.json, restrict permissions such as chmod 600 and keep it out of synced or committed directories. Confirm every local file and message is intended to be sent to Feishu.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
index.js:20
Finding

Shell Command Injection in Exported Image Wrapper Functions

Content
View full analysis
{ let cmd = `node "${TOOL_PATH}" send --file "${filePath}"`; if (target) cmd += ` --target "${target}"`; if (message) cmd += ` --message "${message}"`; exec(cmd, (error, stdout, stderr) => { if (error) { reject(new Error(stderr || error.message)); return; } try { const result = JSON.parse(stdout); resolve(result); } catch (e) { resolve({ success: true, output: stdout }); } }); }); } ``` ```javascript function uploadImage(filePath) { return new Promise((resolve, reject) => { const cmd = `node "${TOOL_PATH}" upload --file "${filePath}"`; exec(cmd, (error, stdout, stderr) => { if (error) { reject(new Error(stderr || error.message)); return; } try { const result = JSON.parse(stdout); resolve(result); } catch (e) { resolve({ success: true, output: stdout }); } }); }); } ``` ### Technical Analysis The exported `sendImage()` and `uploadImage()` functions interpolate caller-controlled values into command strings passed to `child_process.exec()`. The affected inputs are `target`, `filePath`, and `message`. `exec()` invokes a system shell. Placing values inside double quotes does not make them safe because shell command substitution can still occur inside double-quoted strings, and an embedded quote can terminate the intended argument. Consequently, an attacker can provide shell metacharacters or command-substitution syntax that the shell interprets as executable commands. The functions are exported through `module.exports`, so this vulnerability is reachable not ...[truncated 1542 chars]
Remediation
View remediation
{ const args = [TOOL_PATH, 'send', '--file', filePath]; if (target) { args.push('--target', target); } if (message) { args.push('--message', message); } execFile(process.execPath, args, { shell: false }, (error, stdout, stderr) => { if (error) { reject(new Error(stderr || error.message)); return; } try { resolve(JSON.parse(stdout)); } catch { resolve({ success: true, output: stdout }); } }); }); } ``` Apply the same pattern to `uploadImage()`. Additional hardening should include: - Validate Feishu target identifiers against their expected syntax. - Resolve and normalize file paths before use. - Restrict readable image files to explicitly authorized directories when inputs cross a trust boundary. - Reject null bytes and unexpected control characters. - Set execution timeouts and output-size limits. - Avoid attempting to make shell commands safe through manual quoting; eliminate the shell entirely. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:40
Finding

Documentation Promotes Shell Command Injection Pattern

Content
View full analysis
{ if (error) { console.error(`Error: ${error}`); return; } const result = JSON.parse(stdout); console.log('Image sent:', result.message_id); }); ``` ### Technical Analysis The documented OpenClaw integration inserts `userId` and `filePath` directly into a command string passed to `child_process.exec()`. Neither value is quoted, validated, nor passed as an isolated process argument. Because `exec()` evaluates its input through a shell, whitespace and shell metacharacters in either variable are interpreted as shell syntax. A user who copies this example into an integration that accepts externally influenced paths or recipient identifiers can introduce arbitrary command execution. Although this issue is in documentation rather than an executed project module, it presents a concrete downstream security risk because the example explicitly recommends an unsafe integration pattern. ### Attack Path 1. A developer copies the documented example into an OpenClaw or Node.js integration. 2. The integration derives `userId` or `filePath` from a request, generated content, uploaded-file metadata, or another untrusted source. 3. An attacker supplies a value containing a command separator, redirection operator, command substitution, or another shell construct. 4. The application interpolates the value into the command string. 5. `exec()` invokes the system shell, which executes the injected command with the application's privileges. ### Impact Assessment Applications following the documented pattern can expose arbitrary command execution. A successful attacker may access application files, local crede ...[truncated 249 chars]
Remediation
View remediation
{ if (error) { console.error(`Error: ${stderr || error.message}`); return; } const result = JSON.parse(stdout); console.log('Image sent:', result.message_id); } ); ``` The documentation should also: - Explicitly warn against concatenating untrusted values into shell commands. - Recommend validating Feishu recipient identifiers. - Recommend constraining file paths to approved upload or image directories. - Keep all examples consistent with the secure process-execution approach used by the implementation. ]]>

T08 · Insecure Dependencies

Warning
Location
feishu-image-tool.js:15
Finding

Feishu SDK Loaded from an Undeclared Mutable Home-Directory Path

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README instructs users to store long-lived Feishu app credentials in a plaintext file under the home directory without any warning about file permissions, secret handling, or safer alternatives. On shared systems, in backups, or through accidental commits and local disclosure, these credentials could be exposed and then used to send messages or access Feishu APIs as the application.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill can access sensitive environment-based credentials (FEISHU_APP_ID, FEISHU_APP_SECRET) but does not declare any explicit tool scope or permission boundary. This weakens reviewability and increases the chance that operators or users invoke a skill with broader capabilities than expected, especially since the same skill also transmits data to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to provide a local file_path and upload images to Feishu, but it does not clearly warn that local files will leave the system and be sent to an external third-party service. This creates a realistic risk of accidental exfiltration of sensitive screenshots, documents, or other local images by users who may interpret the action as a local-only messaging convenience.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · feishu-image-tool.js (reported line 60)May include surrounding context.

js
throw new Error(
    'Feishu credentials not configured. Please set:\n' +
    '  - Environment variables: FEISHU_APP_ID and FEISHU_APP_SECRET\n' +
    '  - Or create config file: ~/.feishu-image/config.json\n' +
    '    with { "appId": "xxx", "appSecret": "xxx" }'
  );
}

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The tool is described as an image upload/send utility, but when --message is supplied it also sends an additional arbitrary text message as a separate side effect. In an agent setting, this expands the action surface beyond the documented capability and can be abused to exfiltrate data or send unintended content to a Feishu recipient under the guise of an image-only operation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The wrapper builds a shell command string with user-influenced values (filePath, target, and message) and executes it via child_process.exec, which invokes a shell. Quoting with double quotes is not sufficient to prevent shell metacharacter expansion in many shells, so crafted input can trigger arbitrary command execution on the host running the skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code file constructs a command to send an image and optional caption to Feishu, which is a network transmission of user-provided data. While the comments describe functionality, there is no explicit user-facing disclosure, confirmation, or warning in this file about uploading local content to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The function builds a shell command using user-supplied parameters and executes it via child_process.exec. Although subprocess use may be part of the wrapper's purpose, this file does not provide a user-facing notice or confirmation that an external command is being launched with the provided arguments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The uploadImage function sends a local file through an underlying tool, implying network transfer of local data. The code contains no confirmation prompt or user-facing disclosure beyond a developer-oriented comment, so users may not be adequately warned before data leaves the system.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The README presents all user-facing instructions in Chinese and does not indicate that another language is available or that the locale restriction is intentional. Under the language/locale policy, forcing a specific language without user opt-in can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The file header describes the tool as an image upload-and-send utility and shows send usage with a required target, implying the send action performs both steps. However, in code the send action accepts a missing target and then only uploads the image and returns an image_key, which contradicts the documented intent of the send command.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The docstring says sendImage returns a Promise containing a structured object with success, image_key, and optional message_id, implying a defined result shape for sending an image. However, when stdout is not valid JSON, the function resolves with { success: true, output: stdout }, which contradicts that documented contract and can mask what the underlying command actually did.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The comment for uploadImage states it uploads an image and returns an object containing success and image_key. In practice, if the child process emits non-JSON output, the function resolves with { success: true, output: stdout } instead, which conflicts with the documented intent and return contract.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description is written as a Chinese-only skill description ('飞书图片发送工具 - 上传图片并发送消息到飞书聊天') with no indication that language is configurable or that the skill is limited to a Chinese-language audience. Under the policy, forcing a specific language without user opt-in or clear justification can be a natural-language locale violation.

Content

No source excerpt is available for this finding.