T05 · Unauthorized Access and Privilege Escalation
Warning
- Location
- scripts/feishu_file_sender.py:25
- Finding
- Workspace Prefix Confusion Permits Cross-Agent Feishu Account Selection## Vulnerability Details **File Location**: `scripts/feishu_file_sender.py`, lines 25-40 **Vulnerability Type**: Improper workspace authorization boundary validation **Risk Level**: Medium ### Vulnerable Code ```python def resolve_agent_id(config: Dict[str, Any]) -> str: cwd = Path.cwd().resolve() best_match = (0, None) for agent in config.get("agents", {}).get("list", []): workspace = agent.get("workspace") agent_id = agent.get("id") if not workspace or not agent_id: continue workspace_path = Path(workspace).resolve() if str(cwd).startswith(str(workspace_path)): match_len = len(str(workspace_path)) if match_len > best_match[0]: best_match = (match_len, agent_id) if best_match[1]: return best_match[1] raise RuntimeError("Unable to resolve agent id from workspace path") ``` ### Technical Analysis The current working directory is associated with an agent by performing a raw string-prefix comparison: ```python str(cwd).startswith(str(workspace_path)) ``` A string prefix is not equivalent to a filesystem ancestry check. For example, if an agent workspace is `/srv/agents/finance`, a separate directory named `/srv/agents/finance-attacker` also passes this test. The resulting agent ID is subsequently used to select a Feishu account binding and read its `appId` and `appSecret`. Therefore, workspace resolution serves as an authorization boundary, but the implementation does not accurately verify that the process is inside the selected workspace. The credentials are not printed or returned directly. Nevertheless, the script uses the incorrectly selected credentials to obtain a tenant access token, upload a caller-selected local file, and send it to a caller-selected Feishu recipient. This exposes the victim agent's Feishu bot authority as a confused-deputy capability. ### Attack Path ...[truncated 1698 chars]
- Remediation
- ## Remediation Suggestions Replace string-prefix matching with a component-aware filesystem ancestry test: ```python workspace_path = Path(workspace).expanduser().resolve() if cwd == workspace_path or workspace_path in cwd.parents: match_len = len(workspace_path.parts) if match_len > best_match[0]: best_match = (match_len, agent_id) ``` Additional hardening should include: 1. Prefer receiving the active agent ID from a trusted runtime context rather than inferring authorization from the current working directory. 2. Verify that the trusted agent ID, workspace, and Feishu account binding are mutually consistent before reading credentials. 3. Reject ambiguous workspace configurations, including duplicate or overlapping workspace roots. 4. Restrict selectable recipients to the current inbound conversation unless an explicit policy grants broader delivery rights. 5. Consider restricting file paths to the authenticated agent's workspace or a dedicated output directory. 6. Add tests covering sibling paths such as `/workspace`, `/workspace-evil`, `/workspace2`, and legitimate descendants such as `/workspace/output`.
