T09 · Insecure Skill Coding Practices
- Location
handle_event.js:7- Finding
OS Command Injection Through Feishu Event Data
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Feishu messaging skill mostly matches its stated purpose, but several implementation flaws could expose local files, secrets, or command execution when inputs are untrusted.
Review before installing or using in automation. It should only be used with trusted inputs and trusted recipients until the shell command construction is replaced with argument-array execution, fallback sending is made opt-in and blocked after validation failures, and file reads are only performed through explicit --text-file or --image-path options.
handle_event.js:7OS Command Injection Through Feishu Event Data
send_safe.js:35OS Command Injection in the Advertised Safe-Send Wrapper
send.js:82Secret-Detection Failure Falls Back to Transmitting the Detected Secret
send.js:256Implicit File-Path Interpretation Can Disclose Local File Contents
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
const { program } = require('commander');
const path = require('path');
const crypto = require('crypto');
require('dotenv').config({ path: require('path').resolve(__dirname, '../../.env'), quiet: true });
// Optimization: Use shared client with Auth Refresh & Retry
const { fetchWithAuth } = require('../feishu-common/index.js');
This is a real command injection risk. Although the message body is moved into a temp file, the script still interpolates user-controlled values like --target, --color, and especially --title directly into a shell command string passed to execSync, so an attacker can inject shell metacharacters or break quoting to execute arbitrary commands. The misleading safety comments increase concern because they may cause reviewers to overlook the remaining shell exposure.
Webhook-controlled values (userOpenId and especially menuKey) are interpolated directly into a shell command executed with execSync. Because shell metacharacters inside double-quoted arguments can still trigger command substitution in /bin/sh, an attacker who can influence the event payload may achieve command injection and run arbitrary commands on the host.
The response string is fixed in Chinese (收到!你点击了菜单按钮...) and there is no indication that the user can choose a language or that the skill is intentionally limited to a Chinese-language context. This can violate language/locale policy when a skill forces a specific language without opt-in or justification.
The script automatically loads a .env file at startup, which may contain credentials or other sensitive configuration, but there is no user-facing warning, prompt, or explanatory comment indicating that environment secrets are being accessed. For a code file, accessing sensitive environment variables or credentials should have some visible disclosure unless it is clearly documented as part of the skill's stated purpose.
When card sending fails, the code automatically retries by sending the message body as plain text without user confirmation. This can transmit content that the caller did not intend to send in fallback form, and in this file it is especially risky because fallback is reached even after validation failures such as secret-scan aborts.
The code heuristically treats a user-supplied --text value as a filesystem path and reads that file if it exists. In a message-sending tool, this silently expands capability from sending caller-provided text to reading arbitrary local files and then potentially transmitting their contents, which can expose secrets or sensitive documents if the caller input is influenced by an untrusted source.
The code comments indicate reliance on the secret scan as justification for accepting potentially dangerous content, but the actual control is incomplete because fallback sending can retransmit content after the primary path aborts. This creates a mismatch between expected protection and real behavior, allowing sensitive or adversarial content from stdin or files to still be sent over the network under error conditions.
The comment explicitly states that longer prompt injection via arguments is being allowed, which signals awareness of hazardous input patterns and a deliberate relaxation of safeguards. In an agent skill context, normalization of prompt-injection-bearing input increases the chance that untrusted content is accepted and then forwarded to downstream systems or users.
The dependency uses a caret version range, which allows newer minor/patch releases to be installed over time. This weakens build reproducibility and can expose the package to upstream supply-chain issues or unexpected behavior changes if a compromised or breaking release is published.
"author": "",
"license": "ISC",
"dependencies": {
"commander": "^13.1.0",
"dotenv": "^16.6.1"
}
}
The dependency uses a caret version range, which allows newer minor/patch releases to be installed over time. This reduces reproducibility and increases exposure to upstream supply-chain compromise or accidental regressions introduced in later allowed versions.
"license": "ISC",
"dependencies": {
"commander": "^13.1.0",
"dotenv": "^16.6.1"
}
}