Back to skill

Security audit

Feishu Send Message

Security checks for vulnerabilities and agentic risk

Overview

This Feishu reporting skill is purpose-aligned, but it uses local app credentials to send external messages automatically with weak scoping and input validation.

Install only in a controlled Feishu/OpenClaw environment with narrowly scoped app credentials and trusted agents. Confirm recipients and message content are appropriate before allowing autonomous use, and prefer a version that validates agent IDs, restricts receive_id_type, safely JSON-encodes payloads, masks credential metadata in logs, and documents what may be sent externally.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
send.sh:27
Finding

Path Traversal Allows Unauthorized Feishu Credential Selection

Content
View full analysis

Vulnerability Details

File Location: send.sh, lines 10 and 27–40
Vulnerability Type: Path traversal and insufficient access control
Risk Level: High

Vulnerable Code

bash
AGENT=$1

# Configuration file path
CONFIG_FILE="$HOME/.openclaw/openclaw-${AGENT}.json"

if [ ! -f "$CONFIG_FILE" ]; then
    echo "Error: configuration file does not exist: $CONFIG_FILE"
    exit 1
fi

# Read configuration
APP_ID=$(jq -r '.channels.feishu.appId' "$CONFIG_FILE")
APP_SECRET=$(jq -r '.channels.feishu.appSecret' "$CONFIG_FILE")

if [ -z "$APP_ID" ] || [ -z "$APP_SECRET" ] || [ "$APP_ID" == "null" ] || [ "$APP_SECRET" == "null" ]; then
    echo "Error: unable to read Feishu credentials from configuration file"
    exit 1
fi

Technical Analysis

The first command-line argument is used directly when constructing a sensitive configuration-file path. The script does not restrict the argument to a known agent identifier, reject path separators, canonicalize the resulting path, or verify that the resolved file remains under $HOME/.openclaw.

An argument containing traversal components such as ../ can consequently cause the path to resolve outside the intended configuration directory. The selected file must have a .json suffix and contain values at .channels.feishu.appId and .channels.feishu.appSecret, but no other authorization check is performed before those credentials are used.

This violates least privilege because a caller permitted to select an agent can potentially select another readable JSON credential file instead.

Attack Path

  1. An attacker obtains the ability to invoke send.sh and control its agent argument.
  2. The attacker supplies an argument containing traversal components that resolves to another readable JSON file.
  3. The script confirms only that the resulting path identifies a regular file.
  4. jq extracts channels.feishu.appId and `channels.feishu.appSecr ...[truncated 862 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace arbitrary agent selection with an explicit allowlist of supported agent identifiers.
  • At minimum, enforce a strict identifier format containing only letters, digits, underscores, and hyphens.
  • Reject values containing /, \, .., control characters, or leading dots.
  • Resolve the candidate path to its canonical form and verify that it remains inside the canonical $HOME/.openclaw directory.
  • Consider mapping each permitted agent identifier to a fixed configuration path instead of constructing paths from user input.
  • Verify that configuration files are owned by the expected account, are not symbolic links, and have restrictive permissions such as 0600.
  • Run the script with an account that can read only the credential files required for its legitimate function.

T09 · Insecure Skill Coding Practices

Warning
Location
send.sh:63
Finding

Unsafe JSON and URL Construction from Unescaped Input

Content
View full analysis

Vulnerability Details

File Location: send.sh, lines 52–54 and 63–66
Vulnerability Type: Improper input validation and unsafe JSON construction
Risk Level: Medium

Vulnerable Code

bash
TOKEN=$(curl -s -X POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/ \
  -H 'Content-Type: application/json' \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}" | jq -r '.tenant_access_token')

RESULT=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${MSG_TYPE}" \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"receive_id\":\"$TARGET\",\"msg_type\":\"text\",\"content\":\"{\\\"text\\\":\\\"$MESSAGE\\\"}\"}")

Technical Analysis

The script creates JSON by concatenating shell variables into string literals. APP_ID, APP_SECRET, TARGET, and MESSAGE are not JSON-escaped. Quotes, backslashes, newline characters, and other JSON control characters can therefore invalidate the request or alter its parsed structure.

The message payload is particularly fragile because it embeds a serialized JSON object inside the outer JSON document. Correctly escaping this nested content requires two levels of serialization, but the script only inserts fixed backslashes around the expected field syntax and does not escape the supplied message.

MSG_TYPE is also inserted directly into a URL query value without validation or URL encoding. A caller can provide values other than the documented open_id and chat_id, including query delimiters that may alter the request parameters.

This is not shell-command injection: the expansions occur inside quoted shell arguments. The vulnerability affects the structure and integrity of the HTTP requests sent to Feishu.

Attack Path

  1. An attacker invokes the script with control over the target, message, or message-type arguments.
  2. The attacker includes JSON metacharacte ...[truncated 1106 chars]
Remediation
View remediation

Remediation Suggestions

  • Generate every JSON document with a JSON-aware tool rather than string interpolation. For example, use jq -n --arg for each value.
  • Construct the nested message content as a JSON object first, serialize it, and then pass that serialized value into the outer request document.
  • Restrict MSG_TYPE to an exact allowlist containing only open_id and chat_id.
  • Validate target identifiers against the expected Feishu identifier syntax and reject control characters or unexpected delimiters.
  • Use curl --data-binary with a generated payload file or safely generated variable.
  • Use curl --fail-with-body --show-error and inspect both HTTP status codes and Feishu response codes.
  • Apply reasonable input-length limits to recipient identifiers and message content.
  • Add tests covering quotes, backslashes, newlines, Unicode, and control characters in all serialized values.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README is entirely written in Chinese and presents the skill as a general-purpose reporting tool, but it does not offer a language choice or explain that the skill is limited to a Chinese-language audience. For a generally applicable skill, this can violate language/locale policy by implicitly forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly advertises zero-configuration use and automatic scanning/automatic use by agents, which can cause unsolicited invocation without clear user intent. In this context, the skill performs authenticated network actions and sends task results externally, so broad auto-activation materially increases the chance of unintended data disclosure or misuse by any agent that discovers it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation describes obtaining Feishu credentials from local configuration and sending task results over the network, but it does not warn users that content may be automatically transmitted using discovered credentials. Because the skill is designed for autonomous reporting by agents, the lack of disclosure and consent language makes accidental exfiltration of sensitive task outputs more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script prints the Feishu App ID directly to stdout. While an App ID is not as sensitive as an app secret or bearer token, it is still credential-related metadata that can aid reconnaissance, leak into logs/CI output, and make follow-on abuse easier when combined with other exposed secrets. In this skill context, the script also handles the real app secret and access token flow, so unnecessary credential disclosure is more dangerous than in a harmless demo.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · send.sh (reported line 50)May include surrounding context.

sh
# 获取 token
echo "获取 token..."
TOKEN=$(curl -s -X POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/ \
  -H 'Content-Type: application/json' \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}" | jq -r '.tenant_access_token')

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · send.sh (reported line 61)May include surrounding context.

sh
# 发送消息
echo "发送消息..."
RESULT=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${MSG_TYPE}" \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"receive_id\":\"$TARGET\",\"msg_type\":\"text\",\"content\":\"{\\\"text\\\":\\\"$MESSAGE\\\"}\"}")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest sets language: zh-CN, and the document does not offer a user choice of language or explain a justified region-specific restriction. This is a natural-language policy concern because it appears to impose a specific locale by default rather than via explicit opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest sets the skill language to "zh-CN", which indicates a fixed locale. Under the policy rules, forcing a specific language or locale without user opt-in can be a natural-language policy violation unless the constraint is clearly documented and justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file's comments, usage text, and runtime messages are all written in Chinese, with no indication that the skill is intentionally region-specific or that users can choose another language. This can violate a language/locale policy when skills are expected not to force a specific language without opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.