Back to skill

Security audit

Feishu Proactive Messenger

Security checks for vulnerabilities and agentic risk

Overview

This skill is disclosed as a Feishu message sender, but it gives callers broad control over which bot identity sends messages and who receives them.

Install only if you are comfortable letting this skill read OpenClaw Feishu app credentials and send messages through configured bots. Before use, restrict who can invoke it, isolate credentials per agent if possible, remove or constrain caller-controlled --agent use, and limit allowed recipients for each bot account.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
scripts/feishu_proactive_messenger.py:183
Finding
Caller-Controlled Agent Selection Enables Cross-Agent Feishu Account Use## Vulnerability Details **File Location**: `scripts/feishu_proactive_messenger.py:51-78, 183-205` **Vulnerability Type**: Missing authorization check for security-sensitive account selection **Risk Level**: High ### Vulnerable Code ```python def resolve_feishu_account( config: Dict[str, Any], agent_id: str ) -> Tuple[str, str, Optional[str]]: """Returns (app_id, app_secret, default_to).""" bindings = config.get("bindings", []) account_id = None for binding in bindings: if binding.get("agentId") == agent_id: account_id = binding.get("match", {}).get("accountId") if account_id: break if not account_id: raise RuntimeError(f"No Feishu account binding for agent: {agent_id}") accounts = ( config.get("channels", {}) .get("feishu", {}) .get("accounts", {}) ) account = accounts.get(account_id) if not account: raise RuntimeError(f"Feishu account not found: {account_id}") app_id = account.get("appId") app_secret = account.get("appSecret") if not app_id or not app_secret: raise RuntimeError(f"Missing appId/appSecret for account: {account_id}") default_to = account.get("defaultTo") return app_id, app_secret, default_to ``` ```python parser.add_argument( "--agent", default=None, help="Agent id (e.g. coder, data). Auto-detect from cwd if omitted", ) ``` ```python config = load_openclaw_config() agent_id = args.agent or resolve_agent_id(config) app_id, app_secret, default_to = resolve_feishu_account(config, agent_id) receive_id = resolve_receive_id(args.receive_id, default_to) receive_id_type = infer_receive_id_type(receive_id, args.receive_id_type) token = get_tenant_access_token(app_id, app_secret) bot_name = get_bot_name(token) result = send_text_message(token, receive_id, receive_id_type, args.text) ``` ### Technical Analysis The `--agent` argument directly controls which binding is looked ...[truncated 2531 chars]
Remediation
## Remediation Suggestions 1. Remove unrestricted caller control over `--agent` when it determines credential selection. 2. Derive the current agent identity from trusted runtime metadata rather than a command-line argument. 3. If `--agent` must remain available, compare it with the identity resolved from the current workspace and reject mismatches by default. 4. Introduce an explicit authorization policy mapping runtime identities to the Feishu accounts they may use. 5. Store each agent's credentials in an isolated configuration or secret store rather than exposing all account records to every Skill invocation. 6. Apply restrictive filesystem permissions to `~/.openclaw/openclaw.json`. 7. Consider restricting or allowlisting recipient identifiers for each account, particularly when proactive messages are automated. 8. Record security-relevant audit events containing the invoking identity, selected agent account, recipient type, and outcome without logging credentials, access tokens, or message content. 9. Add negative tests proving that one agent cannot select another agent's account through `--agent`.

T08 · Insecure Dependencies

Warning
Location
README.md:44
Finding
Unpinned Requests Dependency Creates Supply-Chain Exposure## Vulnerability Details **File Location**: `README.md:44` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash python3 -m pip install requests ``` ### Technical Analysis The installation instruction retrieves `requests` without a fixed version, lockfile, or cryptographic hash. The exact package artifact and transitive dependency versions installed can therefore change after the Skill has been reviewed. Although the package name is correctly spelled and no explicitly untrusted package index is configured, the instruction does not provide reproducible dependency resolution. A compromised future release, compromised package index, altered local index configuration, or newly incompatible dependency version could affect installations without any change to this project. Python packages and build backends may execute code during installation. The imported dependency also executes in the Skill's runtime process, where it can access the same local configuration and network privileges as the script. ### Attack Path 1. A user follows the documented installation command. 2. `pip` resolves the latest available `requests` release and its dependencies using the user's configured package indexes. 3. If a resolved artifact or relevant index is compromised, malicious installation or runtime code is downloaded. 4. That code executes during package installation, import, or later HTTP operations. 5. It runs with the privileges of the user operating the Skill and may access files and network resources available to that user. This is a supply-chain exposure rather than evidence that the current legitimate `requests` package is malicious. ### Impact Assessment A compromised dependency could execute code with the installing user's privileges. In this Skill's expected environment, that could include access to: - The OpenClaw configuration file. - Feishu application credentials stored in that con ...[truncated 300 chars]
Remediation
## Remediation Suggestions 1. Add a reviewed dependency manifest with exact versions for `requests` and relevant transitive dependencies. 2. Generate and verify cryptographic hashes for every accepted distribution. 3. Install with hash enforcement, for example: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 4. Use a lockfile-producing dependency workflow and commit the lockfile to the project. 5. Prefer a trusted, explicitly configured package index and prevent fallback to unexpected indexes. 6. Periodically review pinned versions for security advisories and update them through a controlled review process. 7. Test supported Python versions against the locked dependency set.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Credential Access

High
Category
Privilege Escalation
Content
1. 通过 `--agent` 参数或 `cwd` 匹配确定当前 agent id。
2. 通过绑定关系从 `~/.openclaw/openclaw.json` 读取 Feishu appId/appSecret。
3. 从同一 account 的 `defaultTo` 读取默认目标(去掉 `user:` 前缀)。
4. 获取 tenant access token。
5. 通过飞书 `bot/v3/info` API 获取 bot 显示名称。
6. 调用消息发送接口(`im/v1/messages`)发送文本消息。
7. 输出 `✅ [Bot名称] 消息已发送`。
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
1. 通过 `--agent` 参数或 `cwd` 匹配确定当前 agent id。
2. 通过绑定关系从 `~/.openclaw/openclaw.json` 读取 Feishu appId/appSecret。
3. 从同一 account 的 `defaultTo` 读取默认目标(去掉 `user:` 前缀)。
4. 获取 tenant access token。
5. 通过飞书 `bot/v3/info` API 获取 bot 显示名称。
6. 调用消息发送接口(`im/v1/messages`)发送文本消息。
7. 输出 `✅ [Bot名称] 消息已发送`。
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
1. 通过 `--agent` 参数或 `cwd` 匹配确定当前 agent id。
2. 通过绑定关系从 `~/.openclaw/openclaw.json` 读取 Feishu appId/appSecret。
3. 从同一 account 的 `defaultTo` 读取默认目标(去掉 `user:` 前缀)。
4. 获取 tenant access token。
5. 通过飞书 `bot/v3/info` API 获取 bot 显示名称。
6. 调用消息发送接口(`im/v1/messages`)发送文本消息。
7. 输出 `✅ [Bot名称] 消息已发送`。
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
1. 通过 `--agent` 参数或 `cwd` 匹配确定当前 agent id。
2. 通过绑定关系从 `~/.openclaw/openclaw.json` 读取 Feishu appId/appSecret。
3. 从同一 account 的 `defaultTo` 读取默认目标(去掉 `user:` 前缀)。
4. 获取 tenant access token。
5. 通过飞书 `bot/v3/info` API 获取 bot 显示名称。
6. 调用消息发送接口(`im/v1/messages`)发送文本消息。
7. 输出 `✅ [Bot名称] 消息已发送`。
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
1. 通过 `--agent` 参数或 `cwd` 匹配确定当前 agent id。
2. 根据 agent id 从 `~/.openclaw/openclaw.json` 读取对应 account 的 appId/appSecret。
3. 从同一 account 的 `defaultTo` 读取默认目标用户(如未通过参数指定)。
4. 获取 tenant access token。
5. 通过飞书 `bot/v3/info` API 获取 bot 显示名称。
6. 调用飞书 **发送消息** API(`im/v1/messages`)发送文本消息。
7. 输出简洁结果:`✅ [Bot名称] 消息已发送`。
Confidence
91% confidence
Finding
This step describes reading appId/appSecret from a local config and exchanging them for a tenant access token, which is direct credential handling. Even if intended for legitimate Feishu messaging, any skill that can access reusable secrets can impersonate the bot account and send messages to arbitrary recipients if misused or modified.

Credential Access

High
Category
Privilege Escalation
Content
1. Determine agent id via `--agent` parameter or by matching `cwd`.
2. Read appId/appSecret from `~/.openclaw/openclaw.json` based on the agent id.
3. Read the default target user from the same account's `defaultTo` (if not specified via args).
4. Obtain a tenant access token.
5. Retrieve the bot's display name via Feishu `bot/v3/info` API.
6. Call Feishu **Send Message** API (`im/v1/messages`) to deliver the text message.
7. Output clean result: `✅ [BotName] 消息已发送`.
Confidence
91% confidence
Finding
The English duplicate of the workflow confirms the same sensitive behavior: local credential retrieval followed by token acquisition and external API use. In context, this is more dangerous because the skill is specifically designed for proactive outbound messaging, which can be abused for impersonation, spam, or data exfiltration through a trusted enterprise channel.

Credential Access

High
Category
Privilege Escalation
Content
- `channels.feishu.accounts.*.appId`
- `channels.feishu.accounts.*.appSecret`

凭证仅用于获取 tenant access token 并发送消息。技能不会存储或向其他地方传输凭证。

This skill reads Feishu credentials from `~/.openclaw/openclaw.json`:
Confidence
88% confidence
Finding
The security section states the skill reads `appId` and `appSecret` from `~/.openclaw/openclaw.json`, confirming access to sensitive authentication material. Claims that credentials are not stored or transmitted elsewhere do not remove the core risk: possession of these secrets enables token minting and bot impersonation.

Credential Access

High
Category
Privilege Escalation
Content
- `channels.feishu.accounts.*.appId`
- `channels.feishu.accounts.*.appSecret`

These values are used only to obtain a tenant access token and send the message.
The skill does not store or transmit credentials anywhere else.

## 备注 | Notes
Confidence
88% confidence
Finding
This repeated statement again confirms that the skill uses sensitive credentials to obtain access tokens and send messages. Because the skill supports all agents and can infer identity from `--agent` or cwd, the surrounding context raises the blast radius: one compromised or confused invocation could use another agent's messaging identity.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill explicitly performs file reads, environment access, and outbound network calls, yet it declares no tool scope or permission boundary. That omission increases risk because an agent or runtime may grant broader capabilities than users expect, especially for a skill that reads local credentials and sends external messages.

Vague Triggers

Medium
Confidence
86% confidence
Finding
This is a manifest file, so vague-trigger review applies. The description explains what the skill does but provides no explicit invocation phrases, scope limits, or negative examples, which can make activation conditions ambiguous and increase the chance of unintended invocation.

External Transmission

Medium
Category
Data Exfiltration
Content
def get_tenant_access_token(app_id: str, app_secret: str) -> str:
    resp = requests.post(
        FEISHU_TOKEN_URL,
        json={"app_id": app_id, "app_secret": app_secret},
        timeout=15,
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"msg_type": "text",
        "content": json.dumps({"text": text}),
    }
    resp = requests.post(
        FEISHU_SEND_MSG_URL,
        headers=headers,
        params=params,
Confidence
80% confidence
Finding
The skill enables proactive outbound messaging to a user- or environment-controlled receive_id using the agent's bound Feishu credentials, with no recipient allowlist, confirmation step, policy check, or content restriction. In the context of an agent skill, this can be abused to exfiltrate agent-generated data or send unauthorized messages to arbitrary chats/users if another component can invoke the script or control its arguments/environment.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The script prints a completion message in Chinese only (`消息已发送`) regardless of the user's language preference. This is a natural-language locale policy issue because the file does not offer a language choice, fallback, or justification for requiring Chinese output.

Natural-Language Policy Violations

Low
Confidence
61% confidence
Finding
The natural-language description centers the skill around Feishu and begins in Chinese, which may imply a language/locale-specific workflow. Because the manifest does not explicitly state that this is a region- or platform-specific skill with user opt-in, it may conflict with language/locale policy expectations.

Static analysis

No suspicious patterns detected.