T09 · Insecure Skill Coding Practices
Warning
- Location
- vendor/zhiqi_agent/cli.py:339
- Finding
- Irreversible Identity Retirement Lacks Enforced Human Confirmation## Vulnerability Details **File Location**: `vendor/zhiqi_agent/cli.py:339-343` **Additional Locations**: `vendor/zhiqi_agent/cli.py:1327-1329`, `vendor/zhiqi_mcp/server.py:99-102`, `vendor/zhiqi_mcp/server.py:299-300`, `vendor/zhiqi_agent/client.py:255-258` **Vulnerability Type**: Missing authorization confirmation for an irreversible operation **Risk Level**: Medium ### Complete Code Snippets ```python def cmd_retire(args): c = _client(args) r = c.retire(args.reason) print("✔ 设备已退役 身份码=%s 状态=%s" % (r.get("agentCode"), r.get("statusText"))) print(" 配额已释放;该身份码进入不可复用名录,历史记录保留。") ``` ```python sp = sub.add_parser("retire", parents=[rate], help="设备退役(释放配额)") sp.add_argument("--reason", default="设备退役") sp.set_defaults(func=cmd_retire) ``` ```python tool("zhiqi_retire", "设备退役(不可逆):吊销凭证、释放身份配额,身份码进入永久不可复用名录,历史记录保留。", {"reason": {"type": "string", "description": "退役原因,可选"}}, []) ``` ```python if name == "zhiqi_retire": return client.retire(args.get("reason") or "设备退役") ``` ```python def retire(self, reason: str = "设备退役") -> dict: ident = self.store.require_identity() return self._request("POST", "/api/v1/identity/identities/%s/retire" % ident["agentCode"], {"reason": reason}) ``` ### Technical Analysis Both exposed entry points immediately execute retirement: - The CLI `retire` subcommand requires only an optional reason and has no confirmation flag or interactive confirmation. - The MCP `zhiqi_retire` tool has no required arguments and directly invokes `client.retire()`. - The client then sends an authenticated retirement request using the local device identity. The MCP description explicitly identifies retirement as irreversible, but descriptive text is not a technical authorization gate. A model or other MCP caller can invoke the operation without supplying a separately controlled indication of informed human consent. The vulnerable trust transition is from a model-level tool decision to a ...[truncated 1473 chars]
- Remediation
- ## Remediation Suggestions 1. Require an explicit confirmation value at every entry point: - Add a CLI option such as `--confirm-retire`. - Add a required MCP field such as `confirmPermanentRetirement: true`. - Reject the operation unless the exact confirmation value is present. 2. For MCP usage, prefer a server-issued, short-lived approval challenge: - First request retirement intent. - Present the identity and irreversible consequences to the human. - Require a human-approved, single-use token before sending the retirement request. 3. Do not rely on tool descriptions or model reasoning as confirmation. Enforce the gate in `AgentClient.retire()` or in a shared wrapper so future entry points cannot bypass it. 4. Bind confirmation to the specific identity being retired and expire it quickly to prevent replay or accidental reuse. 5. Record a security audit event containing the identity code, invocation channel, confirmation method, and timestamp, while excluding private keys and bearer tokens.
