Back to skill

Security audit

M365 (Microsoft) Task Manager by altf1be

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a real Microsoft To Do integration, but it needs review because it persists reusable Microsoft auth tokens without enforcing safe file permissions and overstates Planner, owner, reminder, and assignment capabilities.

Install only if you are comfortable giving this skill delegated access to read, create, update, and delete your Microsoft To Do tasks and to keep a reusable token cache locally. Protect or relocate the token cache, revoke access if the machine is shared or compromised, and do not rely on the advertised Planner, owner assignment, or reminder features unless they are added later.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/m365-todo.mjs:94
Finding
OAuth Token Cache Is Written Without Explicit Restrictive Permissions## Vulnerability Details **File Location**: `scripts/m365-todo.mjs`, lines 94–97 **Vulnerability Type**: Insecure storage of OAuth credentials **Risk Level**: Medium ### Vulnerable Code ```js async function saveCache(pca, cachePath) { const serialized = await pca.getTokenCache().serialize(); fs.writeFileSync(cachePath, serialized, 'utf8'); } ``` ### Technical Analysis The serialized MSAL token cache is sensitive authentication material that may contain access tokens, refresh tokens, and account metadata. The Skill requests the `offline_access` scope, so the cache may permit authentication to be renewed beyond the lifetime of an individual access token. The cache is written using `fs.writeFileSync()` without an explicit restrictive file mode. For a newly created file, effective permissions depend on the host process's umask. If the configured cache file already exists with permissive permissions, this operation does not correct them. Consequently, the cache may be readable by other local users or processes on a shared or misconfigured host. The default location under the user's home directory reduces exposure on normally configured systems, but it does not guarantee secure permissions. The optional `M365_TOKEN_CACHE_PATH` also allows the cache to be placed in a less protected location. ### Attack Path 1. A victim authenticates through the Skill's Microsoft Entra device-code flow. 2. The Skill serializes the MSAL cache after authentication or silent token acquisition. 3. The cache is written to the default or configured path without enforcing mode `0600`. 4. A permissive umask, insecure pre-existing file, or unsafe custom path makes the cache readable by another local account or process. 5. A local attacker copies the serialized token cache. 6. The attacker imports or otherwise uses the cached credentials to obtain Microsoft Graph access as the victim. 7. The attacker reads or modifies resources authorized by the delegated scopes until the credentials ...[truncated 796 chars]
Remediation
## Remediation Suggestions 1. Create the cache directory with owner-only permissions: ```js fs.mkdirSync(path.dirname(cachePath), { recursive: true, mode: 0o700, }); fs.chmodSync(path.dirname(cachePath), 0o700); ``` 2. Write the token cache with mode `0600`, and correct permissions on existing files: ```js fs.writeFileSync(cachePath, serialized, { encoding: 'utf8', mode: 0o600, }); fs.chmodSync(cachePath, 0o600); ``` 3. Use an atomic write strategy: create a temporary file in the same protected directory with `O_CREAT | O_EXCL`, mode `0600`, flush it, and rename it over the destination. 4. Before reading or replacing the cache, use `lstat()` and reject symbolic links and non-regular files. Where supported, use no-follow file-opening semantics to reduce symbolic-link attacks. 5. Validate custom `M365_TOKEN_CACHE_PATH` values and warn or fail if the parent directory or cache file is accessible to group or other users. 6. Prefer an operating-system credential manager or encrypted token-cache persistence rather than a plaintext filesystem cache. 7. Document the sensitivity of the cache, its expected permissions, credential revocation procedures, and the security implications of enabling `offline_access`.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes an M365 task workflow skill centered on Microsoft To Do and Planner operations. The supplied code does not interact with any Microsoft 365 services, APIs, accounts, or task systems. It only transforms two command-line inputs into a normalized string. This is a materially different primary purpose rather than a supporting implementation detail, so the description does not accurately represent the code's actual behavior.

Credential Access

High
Category
Privilege Escalation
Content
},
  });

  if (!device?.accessToken) throw new Error('Failed to acquire access token');
  await saveCache(pca, cachePath);
  return device.accessToken;
}
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill performs operations that require environment access and network access to Microsoft Graph, but the manifest does not explicitly declare those capabilities. Missing tool-scope declarations reduce transparency and can cause an agent or reviewer to underestimate what the skill can access, especially when it can use cached credentials and modify live Microsoft 365 data.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest advertises both Microsoft To Do and Planner workflows, but the setup, permissions, and commands only cover Microsoft To Do. This discrepancy can mislead users and automated systems about the feature set and required trust level, which is risky in a skill that performs real operations against production M365 data.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The skill explicitly supports deleting real Microsoft To Do tasks and caching OAuth tokens locally, but it does not warn users about destructive actions or credential-storage implications. In the context of live Microsoft 365 integrations, lack of warnings increases the chance of accidental data loss and unsafe handling of reusable delegated credentials.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script serializes the MSAL token cache to a predictable file under the user's home directory without setting restrictive permissions or warning the user. If another local process or user can read that file, refresh/access tokens may be exposed and reused to access the victim's Microsoft 365 To Do data.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The manifest promises capabilities such as assigning owners, tracking operational tasks, follow-up, and daily reminders. In contrast, this file only lists, creates, updates, and deletes tasks in the current user's To Do lists, with fields for title, body, due date, and status; there is no code for assigning tasks to others, reminder scheduling, ownership management, or follow-up automation.

Intent-Code Divergence

Low
Confidence
85% confidence
Finding
The documentation states required fields are title, owner, due date, and status, implying task creation and management enforce or support those fields. But the command examples show task creation with only title and due date, and the surrounding docs describe only Microsoft To Do CRUD, which does not demonstrate owner assignment support and does not align with the stated required-field contract.

Description-Behavior Mismatch

Low
Confidence
96% confidence
Finding
The manifest describes managing task workflows with both Microsoft To Do and Planner, suggesting broader Microsoft 365 task coverage. However, the CLI help and all implemented Graph endpoints are limited to `/me/todo/...` operations, with no Planner endpoints, plans, buckets, or assignments handled anywhere in the code.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The due date parser hard-codes the timezone to 'Europe/Brussels', which imposes a locale-specific behavior on all users regardless of their region or preference. This is a natural-language policy concern because it forces a specific locale without offering choice or documenting a justified regional constraint.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/m365-todo.mjs:60