T09 · Insecure Skill Coding Practices
- Location
src/tools/gmail-extra.ts:3090- Finding
Label deletion bypasses code-enforced user confirmation
- Content
View full analysis
Vulnerability Details
File Location:
src/tools/gmail-extra.ts:3090-3099
Vulnerability Type: Destructive operation without user confirmation
Risk Level: MediumVulnerable Code
ts server.registerTool('gog_gmail_labels_delete', { description: 'Delete a Gmail label.', annotations: { destructiveHint: true }, inputSchema: z.object({ labelIdOrName: z.string().describe('Label ID or name to delete'), account: accountParam, }), }, async ({ labelIdOrName, account }) => { return runOrDiagnose(['gmail', 'labels', 'delete', pos(labelIdOrName), '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse });Technical Analysis
The handler unconditionally appends
--force, explicitly bypassing gog's non-interactive safety refusal. ThedestructiveHintannotation informs the client that the operation is destructive but does not enforce approval.The project already contains a host-mediated confirmation and confirmation-token mechanism for higher-risk actions such as sending mail and permanently deleting messages. This label-deletion path does not use that mechanism. Consequently, an MCP caller or agent decision is treated as equivalent to the Gmail account owner's explicit approval.
The attacker-controlled input is
labelIdOrName, while the dangerous operation is the forced deletion performed using the server's authenticated Gmail account. The crossed trust boundary is between an agent-generated tool request and an account-owner-authorized destructive change.Attack Path
- The Skill is connected to an authenticated Gmail account.
- An agent selects or is induced to select a label identifier, potentially while processing untrusted email content.
- The agent invokes
gog_gmail_labels_delete. - The handler automatically adds
--force. - gog deletes the label without a host confirmation prompt or confirmation token.
Impact Assessment
An attacker does not obtain ad ...[truncated 310 chars]
- Remediation
View remediation
Remediation Suggestions
Use the existing
requireDispatchConfirmationmechanism before adding--force.The confirmation should:
- Fetch the current label metadata and counts.
- Display the exact account, label ID, label name, and affected message/thread counts.
- Bind the confirmation token to the account and exact label identifier.
- Re-read the label before deletion and invalidate approval if its identity or relevant metadata changed.
- Append
--forceonly after successful host elicitation or validation of an unexpired, single-use confirmation token. - Refuse the operation when confirmation cannot be displayed and the server is configured for refusal mode.
