Skip to content

Security: Add confirmDestructive() guards for dangerous operations #291

@joshuayoes

Description

@joshuayoes

Summary

Several commands that perform dangerous, hard-to-reverse operations lack confirmDestructive() guards. These commands can silently redirect email, grant mailbox access, or share files without user confirmation — particularly dangerous in agent/MCP mode.

Partially related to #239 (restrict to drafts only) but broader in scope.

Affected Files & Missing Guards

1. internal/cmd/gmail_filters.goGmailFiltersCreateCmd.Run() (line 169)

gmail filters create --forward can silently set up email forwarding to an external address. The delete sub-command has confirmDestructive() (line 354), but create does not, despite --forward being arguably more dangerous than delete.

func (c *GmailFiltersCreateCmd) Run(ctx context.Context, flags *RootFlags) error {
    // No confirmDestructive() here!
    // ...
    if c.Forward != "" {
        action.Forward = c.Forward  // Silently forwards all matching email
    }

2. internal/cmd/gmail_delegates.goGmailDelegatesAddCmd.Run() (line 100)

gmail delegates add grants another user full read access to the mailbox. The remove sub-command has confirmDestructive() (line 154), but add does not.

func (c *GmailDelegatesAddCmd) Run(ctx context.Context, flags *RootFlags) error {
    // No confirmDestructive() here!
    // ...
    delegate := &gmail.Delegate{DelegateEmail: delegateEmail}
    created, err := svc.Users.Settings.Delegates.Create("me", delegate).Do()

3. internal/cmd/drive.goDriveShareCmd.Run() (line 717)

drive share --to=anyone makes a file publicly accessible. The unshare sub-command has confirmDestructive() (line 850), but share does not.

func (c *DriveShareCmd) Run(ctx context.Context, flags *RootFlags) error {
    // No confirmDestructive() here!
    // ...
    perm := &drive.Permission{Role: role}
    // Can set Type: "anyone" — making file public

Risk

In interactive mode, these operations happen silently. In agent/MCP mode, an LLM could be tricked (via prompt injection in email content) into:

  • Creating a forwarding filter that exfiltrates all future email
  • Adding a delegate who gains full mailbox access
  • Sharing sensitive files publicly

Remediation

Add confirmDestructive() calls to all three commands:

// gmail_filters.go - GmailFiltersCreateCmd.Run()
if c.Forward != "" {
    if confirmErr := confirmDestructive(ctx, flags, 
        fmt.Sprintf("create gmail filter forwarding to %s", c.Forward)); confirmErr != nil {
        return confirmErr
    }
}

// gmail_delegates.go - GmailDelegatesAddCmd.Run()
if confirmErr := confirmDestructive(ctx, flags, 
    fmt.Sprintf("add gmail delegate %s (grants mailbox read access)", delegateEmail)); confirmErr != nil {
    return confirmErr
}

// drive.go - DriveShareCmd.Run()
if to == driveShareToAnyone {
    if confirmErr := confirmDestructive(ctx, flags, 
        fmt.Sprintf("share drive file %s with anyone (public)", fileID)); confirmErr != nil {
        return confirmErr
    }
}

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions