T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/feishu_proactive_messenger.py:183- Finding
Caller-Controlled Agent Selection Enables Cross-Agent Feishu Account Use
- Content
View full analysis
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: HighVulnerable 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_topython 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
--agentargument directly controls which binding is looked ...[truncated 2531 chars]- Remediation
View remediation
Remediation Suggestions
- Remove unrestricted caller control over
--agentwhen it determines credential selection. - Derive the current agent identity from trusted runtime metadata rather than a command-line argument.
- If
--agentmust remain available, compare it with the identity resolved from the current workspace and reject mismatches by default. - Introduce an explicit authorization policy mapping runtime identities to the Feishu accounts they may use.
- Store each agent's credentials in an isolated configuration or secret store rather than exposing all account records to every Skill invocation.
- Apply restrictive filesystem permissions to
~/.openclaw/openclaw.json. - Consider restricting or allowlisting recipient identifiers for each account, particularly when proactive messages are automated.
- Record security-relevant audit events containing the invoking identity, selected agent account, recipient type, and outcome without logging credentials, access tokens, or message content.
- Add negative tests proving that one agent cannot select another agent's account through
--agent.
- Remove unrestricted caller control over
