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

Content
View full analysis

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
View 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);
  1. 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);
  1. 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.

  2. 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.

  3. 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.

  4. Prefer an operating-system credential manager or encrypted token-cache persistence rather than a plaintext filesystem cache.

  5. 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.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/m365-todo.mjs (reported line 120)May include surrounding context.

js
},
  });

  if (!device?.accessToken) throw new Error('Failed to acquire access token');
  await saveCache(pca, cachePath);
  return device.accessToken;
}

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

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