T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/main.py:192
- Finding
- Mail Draft Creation and Local File Attachment Bypass Explicit Confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py:192-252` **Vulnerability Type**: Missing authorization check for a state-changing operation **Risk Level**: Medium ### Vulnerable Code ```python def cmd_mail_draft(args, send): action = "mail.send" if send else "mail.draft" to = args.get("to", "").strip() subject = args.get("subject", "") body = args.get("body", "") cc = _split_csv(args.get("cc", "")) bcc = _split_csv(args.get("bcc", "")) attachments = _split_csv(args.get("attachments", "")) if not to: _fail(action, "Missing to=") if send: _confirm_required(action, args) ascript = r''' on run argv set theTo to item 1 of argv set theSubject to item 2 of argv set theBody to item 3 of argv set theCC to item 4 of argv set theBCC to item 5 of argv set theAttachments to item 6 of argv set shouldSend to item 7 of argv tell application "Mail" set newMessage to make new outgoing message with properties {subject:theSubject, content:theBody & return & return, visible:true} tell newMessage make new to recipient at end of to recipients with properties {address:theTo} if theCC is not "" then repeat with a in (paragraphs of theCC) if (a as text) is not "" then make new cc recipient at end of cc recipients with properties {address:(a as text)} end repeat end if if theBCC is not "" then repeat with a in (paragraphs of theBCC) if (a as text) is not "" then make new bcc recipient at end of bcc recipients with properties {address:(a as text)} end repeat end if end tell if theAttachments is not "" then set parts to paragraphs of theAttachments repeat with p in parts set fp to (p as text) if fp is not "" then tell newMessage to make new attachment with properties {file name:fp} at after the last paragraph end if end repeat end if ...[truncated 2462 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Apply explicit confirmation to both sending and draft creation: ```python action = "mail.send" if send else "mail.draft" _confirm_required(action, args) ``` 2. Add `mail.draft` to the confirmation response alternatives and documentation so the behavior is unambiguous. 3. Before approval, return a structured preview containing recipients, subject, body length, and normalized attachment paths. 4. Resolve attachment paths with `os.path.realpath`, reject nonexistent or non-regular files, and optionally restrict attachments to user-approved directories. 5. Consider a two-stage workflow in which the first call validates and previews the draft and a second call uses a short-lived approval token bound to the exact recipients, content, and attachment list. 6. Add regression tests proving that neither draft creation nor attachment access occurs without confirmation. ]]>
