T09 · Insecure Skill Coding Practices
- Location
src/tools/calendar-extra.ts:75- Finding
Google Meet Conference Termination Bypasses User Confirmation
- Content
View full analysis
Vulnerability Details
File Location:
src/tools/calendar-extra.ts:75-86
Vulnerability Type: Unconfirmed destructive operation
Risk Level: MediumVulnerable Code
ts server.registerTool('gog_meet_end', { description: 'End the active conference in a Google Meet space.', annotations: { destructiveHint: true }, inputSchema: z.object({ meetingCode: z.string().describe('Meeting code'), account: accountParam, }), }, async ({ meetingCode, account }) => { return runOrDiagnose( ['meet', 'end', pos(meetingCode), '--force'], { account }, ); // gog gates this op; without --force the runner's --no-input makes it refuse });The same behavior is present in the shipped runtime bundle at
dist/index.js:36838-36849.Technical Analysis
The
gog_meet_endMCP tool performs an immediate destructive operation against the user's authenticated Google account. Its handler unconditionally passes--force, explicitly bypassing gogcli's interactive safety gate.The
destructiveHint: trueannotation only informs the MCP host about the operation's nature; it does not technically require user approval. Unlike other destructive operations in this file, the handler does not callrequireDispatchConfirmation, accept aconfirmToken, or refuse execution when the host cannot elicit confirmation.The meeting code is protected from command-line option injection by
pos(meetingCode), and the runner uses argument-array process spawning rather than a shell. The confirmed issue is therefore not command injection, but the absence of an enforced authorization checkpoint before a destructive action.Attack Path
- The Skill runs with access to a Google account authenticated through gogcli.
- An MCP caller invokes
gog_meet_endand supplies the target meeting code and account. - The handler constructs
meet end <meetingCode> --force. runOrDiagnosedispatches the command without requesting or validating user confirmat ...[truncated 976 chars]
- Remediation
View remediation
Remediation Suggestions
- Invoke
requireDispatchConfirmationbefore callingrunOrDiagnose, showing the meeting code, selected account, and the fact that all participants will be disconnected. - Add
confirmToken: confirmTokenParamto the input schema and implement the existing confirmation-token fallback for MCP hosts that do not support interactive elicitation. - Refuse the operation when confirmation cannot be obtained rather than silently forcing execution.
- Append
--forceonly after successful interactive confirmation or validation of a confirmation token bound to the exact account and meeting code. - Add tests covering acceptance, rejection, unsupported elicitation, stale or mismatched confirmation tokens, and verification that
runOrDiagnoseis never called after refusal.
- Invoke
