Back to skill

Security audit

outlook-todo

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Microsoft To Do integration that stores local OAuth tokens and requires explicit confirmation before changing tasks.

Install only if you are comfortable granting this skill Microsoft To Do read/write access and storing a refresh token locally. Protect ~/.outlook-todo/, avoid committing or backing it up, and use scripts/token.sh clear --yes-i-really-mean-it or Microsoft account consent revocation if you stop using it.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/setup-device-code.sh:116
Finding
Unnecessary User.Read Permission and Account Profile Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup-device-code.sh:116-121` and `scripts/setup-device-code.sh:286-300` **Vulnerability Type**: Excessive OAuth permission and unnecessary access to user profile information **Risk Level**: Low ### Vulnerable Code The device-code flow requests `User.Read` in addition to the permissions required for Microsoft To Do: ```bash ALLOWED_SCOPES=( "offline_access" "https://graph.microsoft.com/User.Read" "https://graph.microsoft.com/Tasks.ReadWrite" ) SCOPE_JOINED="${ALLOWED_SCOPES[*]}" ``` After authentication, the setup script uses this permission to retrieve and print the signed-in account's user principal name: ```bash load_config || die "config missing after save" PROBE=$(curl --silent --show-error --max-time 15 \ -H "Authorization: Bearer $ACCESS" \ -H "Accept: application/json" \ "${OUTLOOK_TODO_GRAPH_BASE}/me?\$select=id,displayName,userPrincipalName") || die "probe transport error" UPN=$(echo "$PROBE" | jq -r '.userPrincipalName // empty') if [[ -z "$UPN" ]]; then # Could be a 401 or a malformed response; show a sanitized snippet SNIP=$(echo "$PROBE" | head -c 200) die "token probe did not return a userPrincipalName: $SNIP" fi ``` ### Technical Analysis The declared functionality is to read and modify Microsoft To Do lists and tasks. Microsoft Graph's `Tasks.ReadWrite` delegated permission provides the required access for those operations. The additional `User.Read` permission is used only for an optional `/me` identity probe and is not necessary for the core task-management functionality. Requesting `User.Read` expands the authority of the issued OAuth token beyond the minimum required scope. The setup script then retrieves `id`, `displayName`, and `userPrincipalName`, and prints the UPN to stderr. Although stderr is appropriate for diagnostics, it is commonly captured by terminal session recording, CI systems, agent runtimes, and centralized logging. ...[truncated 1617 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `https://graph.microsoft.com/User.Read` from `ALLOWED_SCOPES` and from the scope documentation in `SKILL.md`. 2. Remove the `/me` identity probes from both `scripts/setup-device-code.sh` and `scripts/token.sh`. 3. Validate authentication by making a minimal request to a Microsoft To Do endpoint already covered by `Tasks.ReadWrite`, such as retrieving a limited task-list result. 4. Do not print the account UPN by default. If account identity display is considered necessary, place it behind an explicit opt-in flag and clearly disclose the additional permission before authorization. 5. After authentication, validate the returned `scope` field against the expected scope set and warn or fail if unexpected permissions are issued. 6. Add automated tests confirming that: - `User.Read` is not requested; - only approved Microsoft Graph scopes are present; - setup and status operations do not access `/me`; - account identifiers and bearer tokens are never written to output streams. ]]>
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Session Persistence

Medium
Category
Rogue Agent
Content
name: outlook-todo
license: MIT
description: |
  Read and write Microsoft To Do via its own Microsoft Graph device-code login.
  Enumerate task lists, read/filter tasks, and create, update, complete, or delete tasks
  (writes require --apply plus a typed-YES prompt or an explicit --yes flag).
metadata:
Confidence
88% confidence
Finding
The skill intentionally stores persistent OAuth tokens, including a refresh token, under ~/.outlook-todo/ so future sessions can access Microsoft To Do without re-authentication. Persistent delegated credentials increase risk because any local compromise, overly broad file access by another tool, or accidental backup/exfiltration of that directory could grant ongoing access to the user's task data and permit writes via Tasks.ReadWrite.

Session Persistence

Medium
Category
Rogue Agent
Content
#   2. Requests exactly the minimal To Do consent set (documented in SKILL.md):
#         offline_access
#         https://graph.microsoft.com/User.Read
#         https://graph.microsoft.com/Tasks.ReadWrite
#      No shared family token store, no calendar or contacts scopes, no mail,
#      no files, no directory scopes — ever.
#   3. Calls the /devicecode endpoint and prints a short user code + verification URL.
Confidence
86% confidence
Finding
The script intentionally persists OAuth access and refresh tokens to disk, enabling long-lived session reuse via 'offline_access'. If the local account or token file is compromised, an attacker can access and modify the user's Microsoft To Do data without re-authenticating until the token is revoked or expires.

Static analysis

No suspicious patterns detected.