T09 · Insecure Skill Coding Practices
Warning
- Location
- index.js:399
- Finding
- Destructive deletion tools do not technically enforce user confirmation<![CDATA[ ## Vulnerability Details **File Location**: `index.js:399-417` **Vulnerability Type**: Missing authorization safeguard for destructive operations **Risk Level**: Medium ### Vulnerable Code ```js server.registerTool( "delete_monitor", { description: "Irreversibly deletes an Active Monitor. REQUIRES PRIOR EXPLICIT CONFIRMATION FROM THE USER.", inputSchema: { monitor_id: z.number().int().positive().optional(), name: z.string().optional(), }, }, async ({ monitor_id, name }) => { const text = await callRemoteTool("delete_monitor", { monitor_id, name }); return { content: [ { type: "text", text: `[Inform the user about the success of this deletion based on this JSON]:\n${text}`, }, ], }; }, ); ``` The equivalent `delete_watchdog` handler at `index.js:419-439` has the same weakness. ### Technical Analysis The requirement for explicit confirmation is present only in the behavioral prompt and tool description. These are advisory instructions to the Agent, not security controls enforced by the tool implementation. The deletion handlers accept a resource identifier and immediately forward the destructive operation to the remote Watch.dog API using the configured account API key. They do not require a confirmation parameter, verify a short-lived authorization token, maintain confirmation state, or reject direct calls made without a preceding confirmation exchange. Consequently, an MCP client, a malfunctioning Agent, or an Agent influenced by prompt injection can bypass the documented confirmation workflow and invoke the deletion tool directly. The schemas also allow both identifiers to be omitted or supplied simultaneously, leaving ambiguous requests to the remote service. ### Attack Path 1. An attacker influences the Agent through malicious content, or an MCP client directly issues a `delete_monitor` or `delete_watchdog` tool call. 2. The caller supplies a ...[truncated 770 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Add a mandatory confirmation field to each destructive tool schema, such as `confirmed: z.literal(true)`, and reject every request where it is absent. 2. Prefer a two-step workflow: - A preparation operation resolves the target and returns its exact identity plus a short-lived, single-use confirmation token. - The deletion operation requires that token and validates its target, action, account, and expiration. 3. Enforce confirmation in trusted application code rather than relying on prompt text or tool descriptions. 4. Require exactly one of `monitor_id` or `name` and reject missing or conflicting identifiers. 5. Resolve names to immutable IDs before confirmation so the confirmed target cannot change between steps. 6. Record an audit event containing the target, confirmation time, requesting principal, and API result. 7. Apply the same controls to both `delete_monitor` and `delete_watchdog`. ]]>
