Back to skill

Security audit

Feishu Card

Security checks for vulnerabilities and agentic risk

Overview

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.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
handle_event.js:7
Finding

OS Command Injection Through Feishu Event Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
send_safe.js:35
Finding

OS Command Injection in the Advertised Safe-Send Wrapper

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
send.js:82
Finding

Secret-Detection Failure Falls Back to Transmitting the Detected Secret

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
send.js:256
Finding

Implicit File-Path Interpretation Can Disclose Local File Contents

Content
View full analysis
:"|?*]/.test(options.text); if (isPotentialPath && fs.existsSync(options.text)) { console.log(`[Smart Input] Treating --text argument as file path: ${options.text}`); try { contentText = fs.readFileSync(options.text, 'utf8'); } catch (e) { contentText = options.text; } } else { contentText = options.text; // Removed strict length check to allow longer prompt injection via args if needed, relying on secret scan } ``` ### Technical Analysis The `--text` option is documented as literal message text, while `--text-file` is the explicit file-input option. Nevertheless, `resolveContent()` silently treats short, path-like `--text` values as local filesystem paths whenever the named path exists. This behavior violates the principle of explicit authority. A caller intending to send a literal filename can instead cause the file's contents to be read and transmitted. If an attacker can influence CLI arguments while also choosing or controlling the recipient, the behavior becomes an arbitrary readable-file disclosure primitive. There is no allowed-directory restriction, path canonicalization policy, confirmation prompt, or explicit opt-in for this implicit file access. The secret-scanning fallback vulnerability further weakens protection for sensitive file contents. ### Attack Path 1. An attacker or untruste ...[truncated 1076 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · send.js (reported line 6)May include surrounding context.

js
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');

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

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.

Content

Scanner excerpt · package.json (reported line 13)May include surrounding context.

json
"author": "",
  "license": "ISC",
  "dependencies": {
    "commander": "^13.1.0",
    "dotenv": "^16.6.1"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

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.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
"license": "ISC",
  "dependencies": {
    "commander": "^13.1.0",
    "dotenv": "^16.6.1"
  }
}