T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/move-to-inbox.mjs:20
- Finding
- Message is moved to Inbox without the documented user confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/move-to-inbox.mjs:20-29` **Related Documentation**: `SKILL.md:28-29, 71-73` **Vulnerability Type**: Missing authorization confirmation for a mailbox mutation **Risk Level**: Medium ### Vulnerable Code ```js // Move to Inbox (POST to move) const url = `${base}/messages/${encodeURIComponent(id)}/move`; const result = await graphFetch(url, { method: 'POST', token, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ destinationId: inbox.id }), }); console.log(`✅ Moved message ${id} to Inbox`); console.log(` New location: ${inbox.displayName}`); ``` The documented policy states: ```md # Move a false positive to inbox (requires confirmation) ... In review mode, the script always prompts for confirmation before moving emails. ``` ### Technical Analysis The script obtains a `Mail.ReadWrite` token and immediately submits the Microsoft Graph `move` operation after parsing the command-line arguments. It does not prompt the user, require a `--yes` or `--automatic` option, or otherwise verify that the user has approved the specific mailbox, message, and destination. This contradicts the Skill's declared controlled-mutation policy. Although `Mail.ReadWrite` is functionally necessary to move a message, the lack of an approval boundary allows the permission to be exercised without the documented user interaction. ### Attack Path 1. An Agent, automation process, or user invokes `move-to-inbox.mjs` with a profile, mailbox, and message ID. 2. The caller expects a confirmation prompt because the Skill documentation says one is required. 3. The script loads the cached Microsoft 365 credential and requests a `Mail.ReadWrite` token. 4. It locates the Inbox and immediately sends `POST /messages/{id}/move`. 5. The selected message is moved before the user has an opportunity to review or reject the action. An attacker who can influence the message ID or generated command could ther ...[truncated 506 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Prompt for confirmation by default and display the mailbox, message ID, source action, and destination before executing the request. 2. Require an explicit non-interactive option such as `--yes` or `--automatic` to bypass the prompt. 3. Refuse non-interactive execution without that explicit option. 4. Consider retrieving and displaying the message sender and subject before approval so the user can validate the selected item. 5. Update the documentation to describe the exact confirmation and automation controls. 6. Record a concise audit event after approval without logging access tokens or message content unnecessarily. ]]>
