Back to skill

Security audit

OpenClaw Feishu Multi-Agent

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for setting up OpenClaw and Feishu multi-agent workflows, but it makes broad persistent agent/configuration changes and handles secrets and paths with insufficient safeguards.

Install only if you understand and want it to modify OpenClaw agent routing and identity/session files. Use dry-run first, inspect every planned path, keep roles files trusted, avoid putting real appSecret values in shareable role files or generated artifacts, and isolate this setup from unrelated OpenClaw sessions if possible.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/apply_feishu_multi_agent.py:75
Finding

Global Session Visibility Violates Least-Privilege Boundaries

Content
View full analysis
list[str]: changes: list[str] = [] tools = ensure_dict_path(config, ["tools"]) sessions = ensure_dict_path(tools, ["sessions"]) if sessions.get("visibility") != "all": sessions["visibility"] = "all" changes.append("set tools.sessions.visibility=all") agent_to_agent = ensure_dict_path(tools, ["agentToAgent"]) if agent_to_agent.get("enabled") is not True: agent_to_agent["enabled"] = True changes.append("set tools.agentToAgent.enabled=true") existing_allow = agent_to_agent.get("allow") if not isinstance(existing_allow, list): existing_allow = [] agent_to_agent["allow"] = existing_allow for role in roles: if role["agentId"] not in existing_allow: existing_allow.append(role["agentId"]) changes.append(f"allow agentToAgent: {role['agentId']}") return changes ``` The audit utility also treats global visibility as mandatory: ```python allow = set(dotted_get(config, ["tools", "agentToAgent", "allow"], []) or []) sessions_visibility = dotted_get(config, ["tools", "sessions", "visibility"]) agent_to_agent_enabled = dotted_get(config, ["tools", "agentToAgent", "enabled"]) if sessions_visibility != "all": failures.append("tools.sessions.visibility should be 'all'") if agent_to_agent_enabled is not True: failures.append("tools.agentToAgent.enabled should be true") ``` Generated configuration contains the same setting: ```python "tools": { "sessions": {"visibility": "all"}, "agentToAgent": {"enabled": True, "allow": allow}, }, ``` ### Technical Analysis The Skill enabl ...[truncated 1674 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
scripts/render_feishu_multi_agent.py:98
Finding

Untrusted Role Fields Are Written into Persistent Agent Instructions

Content
View full analysis
tuple[str, list[dict[str, Any]]]: data = load_json(path) roles = data.get("roles") if not isinstance(roles, list) or not roles: raise ValueError("roles file must contain a non-empty 'roles' array") coordinators = [role for role in roles if role.get("isCoordinator")] if len(coordinators) != 1: raise ValueError("roles file must contain exactly one coordinator") for role in roles: for key in ("agentId", "roleName", "accountId", "openId", "responsibility"): if not role.get(key): raise ValueError(f"role {role!r} is missing required field: {key}") trigger_terms = role.get("triggerTerms", []) if not isinstance(trigger_terms, list) or not all(isinstance(x, str) and x for x in trigger_terms): raise ValueError(f"role {role['agentId']} has invalid triggerTerms") return data.get("systemName", "OpenClaw Feishu Multi-Agent"), roles ``` Those values are interpolated directly into instruction-bearing Markdown: ```python def render_identity(role: dict[str, Any], coordinator_name: str) -> str: trigger_text = "、".join(role["triggerTerms"]) if role["isCoordinator"]: extra = """ ## 飞书群协作 你是默认总调度。群里出现一个新问题时,先判断: 1. 这件事值不值得做 2. 该由谁主答 3. 是否需要多人并行讨论 只要需要别人参与,就必须同时做两步: 1. 在群里用飞书 `` 显式点名 2. 对目标 agent 调用 `sessions_send` 绝对禁止: - 只发裸文本 `@角色` - 只发 `` 不发 `sessions_send` - 给 `sessions_send` 传 `agentId` """ else: extra = f""" ## 飞书群协作 如果 {coordinator_name} 或其 ...[truncated 2685 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apply_feishu_multi_agent.py:156
Finding

Unvalidated Role Paths Permit Writes Outside Intended Directories

Content
View full analysis
Path: raw = role.get("workspace") if raw and not is_placeholder(raw): return Path(raw).expanduser().resolve() raw = role.get("agentDir") if raw and not is_placeholder(raw): return Path(raw).expanduser().resolve() return role_default_dir(state_dir, role) def role_agent_dir(role: dict[str, Any], state_dir: Path) -> Path: raw = role.get("agentDir") if raw and not is_placeholder(raw): return Path(raw).expanduser().resolve() return role_default_dir(state_dir, role) ``` The apply workflow writes an identity file to the resulting directory: ```python def apply_identity_files( roles: list[dict[str, Any]], coordinator_name: str, state_dir: Path, write: bool, backup: bool, ) -> list[str]: changes: list[str] = [] for role in roles: target_dir = role_agent_dir(role, state_dir) target = target_dir / "IDENTITY.md" content = render_identity(role, coordinator_name) if target.exists() and target.read_text(encoding="utf-8") == content: continue changes.append(f"write {target}") if write: target_dir.mkdir(parents=True, exist_ok=True) if backup and target.exists(): backup_file(target) target.write_text(content, encoding="utf-8") return changes ``` The renderer also uses an unvalidated `agentId` as part of an output filename: ```python for role in roles: target = identitie ...[truncated 2163 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/common.py:18
Finding

Feishu Application Secrets Are Written Without Enforced Restrictive Permissions

Content
View full analysis
None: path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") ``` Generated artifacts also include the secret: ```python accounts = { role["accountId"]: { "name": role["roleName"], "appId": role.get("appId") if not is_placeholder(role.get("appId")) else "replace_me", "appSecret": role.get("appSecret") if not is_placeholder(role.get("appSecret")) else "replace_me", } for role in roles } ``` The full roles structure is duplicated into another output file: ```python (output_dir / "openclaw.generated.json").write_text( render_openclaw_snippet(roles, state_dir), encoding="utf-8" ) (output_dir / "roles.generated.json").write_text( json.dumps({"systemName": system_name, "roles": roles}, ensure_ascii=False, indent=2), encoding="utf-8", ) ``` ### Technical Analysis Real `appSecret` values supplied in a roles file can be written into the live OpenClaw configuration, `openclaw.generated.json`, and `roles.generated.json`. These files are created through ordinary `Path.write_ ...[truncated 1396 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code only performs static validation of configuration and roles data for an OpenClaw + Feishu multi-agent setup. While this partially aligns with the declared 'audit existing configs' aspect, it does not implement most of the broader described functionality: teaching coordinator/specialist agents, enabling delegation and handoffs in chats, scaffolding new setups, repairing metadata, or generating artifacts. The primary purpose in the description is a multifunction workflow-building and troubleshooting skill, but the actual code is narrowly an audit CLI. That is a material description/behavior mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill instructs reading and potentially modifying local configuration and identity files under ~/.openclaw, but it does not declare any explicit tool scope or permissions. That creates an authorization transparency gap: a caller may invoke a skill with file access behavior that is broader than the metadata suggests, increasing the chance of unintended local file reads or writes.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
76% confidence
Finding

This duplicate finding points to the same persistence risk: the skill promotes optional write-back into ~/.openclaw, which can permanently change agent configuration and session behavior. In the context of a multi-agent coordination skill, those changes may affect message routing, visibility, and delegated execution across future runs, making mistakes or abuse more consequential.

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

--apply-identities

text

加上 `--write --backup` 才会真正写入 `~/.openclaw/`。

### 2. 生成可落地模板

Session Persistence

Medium
Category
Rogue Agent
Confidence
76% confidence
Finding

This duplicate finding points to the same persistence risk: the skill promotes optional write-back into ~/.openclaw, which can permanently change agent configuration and session behavior. In the context of a multi-agent coordination skill, those changes may affect message routing, visibility, and delegated execution across future runs, making mistakes or abuse more consequential.

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

--apply-identities

text

加上 `--write --backup` 才会真正写入 `~/.openclaw/`。

### 2. 生成可落地模板

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instruction '中文说明为主' sets a default language requirement in natural language. This is a locale/language policy concern because the skill does not offer the user a language choice or indicate that Chinese output is optional.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill reference content is entirely in Chinese and does not indicate that users may choose another language or that the locale is intentionally restricted. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code copies appId and appSecret values from the roles data into the local configuration and later persists that configuration to disk. Although the script supports dry-run mode and prints planned changes, it does not explicitly warn the user that sensitive credential material may be written into ~/.openclaw/openclaw.json.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The generated OpenClaw config emits appId and appSecret fields directly into openclaw.generated.json, sourcing them from the roles data if present. This creates a real secret-handling risk because generated artifacts are commonly checked into source control, shared for troubleshooting, or left with permissive filesystem access, exposing Feishu credentials beyond their intended scope.

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 · scripts/render_feishu_multi_agent.py (reported line 192)May include surrounding context.

python
def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--roles", required=True, help="Path to roles.json")
    parser.add_argument("--output-dir", required=True, help="Directory to write generated artifacts")
    parser.add_argument(
        "--state-dir",
        default="~/.openclaw",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code performs persistent file modification by mutating session data and writing it back to disk. Although the CLI includes a --fix flag and prints a post-write message, there is no pre-action confirmation, cautionary comment/docstring, or explicit user-facing warning that enabling this flag will alter OpenClaw state files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The role inventory template explicitly includes sensitive secrets such as appSecret alongside non-secret metadata, but provides no warning, masking guidance, or secure-handling instructions. In a collaboration-oriented skill, users may paste real credentials into shared docs, chats, or version-controlled files, leading to accidental secret disclosure and subsequent compromise of Feishu applications or agent accounts.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file includes test utterances built around @{coordinatorTrigger} but never defines a narrow, explicit set of allowed trigger phrases or exclusion conditions. The surrounding examples describe common-language requests like asking someone to discuss or decide who should handle an issue, which could overlap with ordinary chat and lead to unintended invocation patterns.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file describes an apply script that can write into ~/.openclaw/ and agent directories when flags such as --write or --apply-identities are used. Although it notes dry-run and backup behavior, it does not clearly warn users that these actions modify local configuration and may affect existing agent behavior or data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The document recommends a script to scan or repair Feishu group session metadata, which can affect active routing state. While the purpose is explained, there is no direct warning that repairing session metadata may alter live behavior and should be validated carefully before applying changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

When --apply-identities and --write are used, the script creates directories and writes IDENTITY.md files for each role. The action is logged as planned changes, but there is no explicit warning in the help text or docstring that enabling this flag will create or overwrite per-agent files under the state directory.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.