Outlook Delegate

Security checks across malware telemetry and agentic risk

Overview

This Outlook delegate skill is transparent about its purpose, but it needs Review because it can send as another user, change or delete mailbox/calendar data, and expose OAuth tokens.

Install only if you intentionally want an assistant account to manage another person's Outlook mailbox and calendar. Prefer Send on Behalf over Send As when transparency matters, avoid the access-token print command, require human approval before sending or deleting items, and grant only the Microsoft 365 permissions needed for your specific workflow.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (17)

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill documents extensive shell-based capabilities but does not declare permissions or clearly constrain when those commands may be used. In an agent ecosystem, hidden shell capability increases the risk that an assistant can execute sensitive mailbox-management operations without transparent consent or policy enforcement.

Context-Inappropriate Capability

Medium
Confidence
99% confidence
Finding
The `get` command prints the raw OAuth access token directly to stdout, making credential exfiltration trivial through logs, shell history capture, calling wrappers, or downstream tools. For a delegate Outlook skill, exposing a bearer token is broader than the stated purpose because anyone obtaining it can act with the delegated Microsoft Graph privileges until expiry and potentially refresh or pivot depending on stored credentials.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This skill is explicitly designed to access and act on another user's mailbox and calendar, including reading, deleting, and sending mail as or on behalf of the owner. Without a prominent authorization and privacy warning, an agent could normalize highly sensitive delegated access and perform actions on private communications without informed user approval.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation instructs users to place a client secret in a local config file, which materially increases the chance of accidental disclosure through backups, logs, file sharing, or weak workstation hygiene. Although later sections mention file permissions, the setup flow lacks a strong upfront warning that this secret enables access to delegated mailbox data.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The delete command performs an irreversible calendar deletion action immediately once invoked, with no confirmation prompt, dry-run mode, or secondary validation of the resolved event ID. In an agentic context where tool calls may be composed from ambiguous user input or partial IDs, this increases the chance of accidental destructive actions against another user's calendar.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script exposes destructive mailbox actions such as delete, archive, and move as immediate one-shot operations with no inline confirmation, dry-run mode, or explicit warning at the point of execution. In an agent setting, this increases the risk that a prompt injection, ambiguous instruction, or model mistake causes unintended mailbox modification or data loss in the owner's mailbox.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The sendMail paths transmit recipient, subject, and body content to Microsoft Graph immediately without an explicit confirmation or disclosure at send time. In an autonomous or tool-using agent context, this makes misdirected, spoofed, or prompt-injected outbound email materially more likely, especially because the skill also supports delegated sending identities.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
Printing an access token to stdout without an explicit warning is dangerous because stdout is commonly captured by terminals, logs, agent traces, CI output, and parent processes. In this delegate-access context, disclosure of the token could grant mailbox and calendar access for both the delegate's identity and delegated owner resources allowed by Graph.

Excessive Permissions

Low
Category
Privilege Escalation
Content
### 2. Configure API Permissions

In your app → API permissions → Add a permission → Microsoft Graph → Delegated permissions:

**Required for all modes:**
- `Mail.ReadWrite` — Read/write assistant's own mail
Confidence
74% confidence
Finding
permissions: *

Credential Access

High
Category
Privilege Escalation
Content
## Files

- `~/.outlook-mcp/config.json` — Configuration (client ID, tenant ID, emails, timezone)
- `~/.outlook-mcp/credentials.json` — OAuth tokens (access + refresh)

## Changelog
Confidence
95% confidence
Finding
credentials.json

Credential Access

High
Category
Privilege Escalation
Content
# All times are handled in the configured timezone.

CONFIG_DIR="$HOME/.outlook-mcp"
CREDS_FILE="$CONFIG_DIR/credentials.json"
CONFIG_FILE="$CONFIG_DIR/config.json"

# Load token
Confidence
82% confidence
Finding
credentials.json

Credential Access

High
Category
Privilege Escalation
Content
ACCESS_TOKEN=$(jq -r '.access_token' "$CREDS_FILE" 2>/dev/null)

if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
    echo '{"error": "No access token. Run outlook-token.sh refresh or complete setup."}'
    exit 1
fi
Confidence
84% confidence
Finding
access token

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Helper: find full event ID from partial suffix
find_full_event_id() {
    local PARTIAL_ID="$1"
    curl -s "$API/calendar/events?\$top=200&\$select=id&\$orderby=start/dateTime%20desc" \
        -K "$AUTH_HEADER_FILE" | \
        jq -r --arg suffix "$PARTIAL_ID" '.value[] | select(.id | endswith($suffix)) | .id' | head -1
}
Confidence
79% confidence
Finding
curl -s "$API/calendar/events?\$top=200&\$select=id&\$orderby=start/dateTime%20desc" \ -K

Tool Parameter Abuse

High
Category
Tool Misuse
Content
exit 1
        fi
        
        curl -s "$API/calendar/events/$FULL_ID" \
            -K "$AUTH_HEADER_FILE" \
            -H "Prefer: outlook.timezone=\"$TIMEZONE\"" | jq 'if .error then {error: .error.message} else {
                subject,
Confidence
78% confidence
Finding
curl -s "$API/calendar/events/$FULL_ID" \ -K

Tool Parameter Abuse

High
Category
Tool Misuse
Content
exit 1
        fi
        
        RESULT=$(curl -s -w "\n%{http_code}" -X DELETE "$API/calendar/events/$FULL_ID" \
            -K "$AUTH_HEADER_FILE")
        
        HTTP_CODE=$(echo "$RESULT" | tail -1)
Confidence
91% confidence
Finding
curl -s -w "\n%{http_code}" -X DELETE "$API/calendar/events/$FULL_ID" \ -K

Tool Parameter Abuse

High
Category
Tool Misuse
Content
;;
        esac
        
        curl -s -X PATCH "$API/calendar/events/$FULL_ID" \
            -K "$AUTH_HEADER_FILE" \
            -H "Content-Type: application/json" \
            -d "$UPDATE_JSON" | jq 'if .error then {error: .error.message} else {status: "event updated", subject: .subject, start: .start.dateTime[0:16], end: .end.dateTime[0:16], id: .id[-20:]} end'
Confidence
84% confidence
Finding
curl -s -X PATCH "$API/calendar/events/$FULL_ID" \ -K

Tool Parameter Abuse

High
Category
Tool Misuse
Content
fi
        
        # Query with timezone
        curl -s "$API/calendarView?startDateTime=$START&endDateTime=$END&\$select=subject,start,end" \
            -K "$AUTH_HEADER_FILE" \
            -H "Prefer: outlook.timezone=\"$TIMEZONE\"" | jq 'if .error then {error: .error.message} else (if (.value | length) == 0 then {status: "free", owner: "'"$OWNER_EMAIL"'", start: "'"$START"'", end: "'"$END"'", timezone: "'"$TIMEZONE"'"} else {status: "busy", owner: "'"$OWNER_EMAIL"'", events: [.value[] | {subject: .subject, start: .start.dateTime[0:16], end: .end.dateTime[0:16]}], timezone: "'"$TIMEZONE"'"} end) end'
        ;;
Confidence
72% confidence
Finding
curl -s "$API/calendarView?startDateTime=$START&endDateTime=$END&\$select=subject,start,end" \ -K

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal