Back to skill

Security audit

Ms Graph Calendar

Security checks for vulnerabilities and agentic risk

Overview

This calendar helper is mostly aligned with scheduling work, but it handles Microsoft Graph credentials and calendar data in unsafe and under-disclosed ways.

Install only if an administrator intentionally approves organization-wide Microsoft Graph application access. Rotate any secret or token that may have been used with this version, avoid running setup with secrets in command-line history, and restrict the app to specific mailboxes before use. Expect the skill to expose employee directory data and detailed calendar metadata, not just open meeting times.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get-token.js:59
Finding

Microsoft Graph Bearer Token Exposed Through Standard Output and an Unsafe Predictable Temporary File

Content
View full analysis
data.expires_at - 60000) { console.error("❌ Token expired. Run get-token.js again."); process.exit(1); } return data.access_token; } ``` Equivalent token-loading behavior appears in `scripts/find-meeting-times.js:37-49` and `scripts/list-users.js:21-33`. ### Technical Analysis The access token is written to a fixed filename in the operating system's shared temporary directory. `fs.writeFileSync()` is used without an explicit restrictive file mode, exclusive creation, symbolic-link protection, ownership verification, or atomic replacement. The resulting permissions depend on the process umask and may allow other local accounts to read the file. A local attacker may also pre-create the predictable path as a symbolic link, causing the token to be written through that link. The full bearer token is additionally printed to standard output. This exposes it to terminal scrollback, agent execution transcripts, CI/CD logs, process-output collectors, and any parent process that capture ...[truncated 1594 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.js:9
Finding

Azure Client Secret Accepted as a Command-Line Argument

Content
View full analysis
{ const i = args.indexOf(flag); return i !== -1 ? args[i + 1] : null; }; const tenantId = get("--tenant-id"); const clientId = get("--client-id"); const clientSecret = get("--client-secret"); ``` `SKILL.md:25-30` instructs users and agents to invoke the script in this form: ```bash node skills/ms-graph-calendar/scripts/setup.js \ --tenant-id \ --client-id \ --client-secret ``` ### Technical Analysis Command-line arguments are not an appropriate transport for long-lived credentials. Depending on the operating system and execution environment, arguments may be exposed through process inspection interfaces, administrative monitoring tools, shell history, audit records, job metadata, debugging output, or agent command transcripts. The client secret is more sensitive than the short-lived access token because it can be repeatedly used with the tenant ID and client ID to request new tokens until the secret expires or is revoked. Although `setup.js` saves the resulting configuration file with mode `0600`, that protection does not address disclosure while the secret is present in the command line. ### Attack Path 1. A user or agent follows `SKILL.md` and runs `setup.js` with `--client-secret`. 2. The complete client secret becomes part of the process argument vector and may also be retained in shell history or an agent execution transcript. 3. A local user, monitoring service, administrator, or party with access to retained execution logs retrieves the tenant ID, client ID, and client secret. 4. The attacker submits a client-credentials token request to the Azure AD tenant using ...[truncated 722 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:173
Finding

Security Documentation Incorrectly Claims Credentials Are Environment-Only and Never Echoed

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is described as a calendar availability helper, but its documented behavior includes obtaining app-only OAuth tokens, reading client secrets, caching credentials locally, and potentially exposing bearer tokens through command output. That mismatch hides sensitive authentication handling behind an innocuous description, increasing the chance of unsafe invocation and secret exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is described as a calendar availability helper, but its documented behavior includes obtaining app-only OAuth tokens, reading client secrets, caching credentials locally, and potentially exposing bearer tokens through command output. That mismatch hides sensitive authentication handling behind an innocuous description, increasing the chance of unsafe invocation and secret exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is described as a calendar availability helper, but its documented behavior includes obtaining app-only OAuth tokens, reading client secrets, caching credentials locally, and potentially exposing bearer tokens through command output. That mismatch hides sensitive authentication handling behind an innocuous description, increasing the chance of unsafe invocation and secret exposure.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The instructions center on obtaining an app-only access token and storing it for later calls, which is sensitive credential material that can grant broad Microsoft Graph access if exposed. Combined with local secret storage and script-based execution, this creates a real risk of token leakage through logs, stdout, process arguments, shell history, or insecure file handling.

Content

Scanner excerpt · SKILL.md (reported line 70)May include surrounding context.

Instructions

Step 1 — Get Access Token

Before any Graph API call, get an app-only token:

bash
node skills/ms-graph-calendar/scripts/get-token.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 145)May include surrounding context.

md
2. Runs `find-meeting-times.js` with date range = this Mon–Fri

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 151)May include surrounding context.

md
2. Runs `get-schedule.js` for tomorrow 12:00–18:00

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 157)May include surrounding context.

md
2. Runs `get-schedule.js` for tomorrow 12:00–18:00

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 168)May include surrounding context.

md
| `404 Not Found` | User email doesn't exist | Verify email via `list-users.js` |

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/get-token.js (reported line 2)May include surrounding context.

js
#!/usr/bin/env node
// get-token.js — ดึง App-only Access Token จาก Azure AD
// ใช้: node get-token.js
// Output: พิมพ์ token ออกมา (หรือเก็บไว้ใน /tmp/openclaw-graph-token.json)

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

This script performs tenant directory enumeration of users and groups, which exceeds the stated skill purpose of checking calendar availability. In the skill context, exposing broad directory lookup capability materially increases privacy and reconnaissance risk because an agent meant for scheduling can now discover employee identities, emails, and group memberships unrelated to a specific meeting task.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares executable capabilities and required environment secrets but does not define an explicit tool scope such as allowed tools or permissions boundaries. In practice, this weakens policy enforcement and makes it easier for a broadly-triggered scheduling skill to invoke shell commands and access sensitive credentials without clear guardrails.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger text is broad enough to match common scheduling-related prompts, which can cause the skill to activate in contexts where users did not intend company-wide calendar or directory access. Because the skill can query employee availability using app-only permissions, overbroad activation increases privacy and data-minimization risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description does not prominently warn that the skill accesses other employees' calendar availability and directory information across the company. Without that disclosure, users may trigger the skill without understanding the privacy implications or the breadth of organizational data being queried.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script hardcodes the locale "th-TH" when formatting meeting times, which forces Thai-language/date formatting for all users regardless of their preferences. This is a natural-language/locale policy issue because no choice or opt-in is offered and the file does not document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code batches employee email addresses and posts them to the Graph getSchedule API, which returns availability and schedule item details for multiple people. Although the script logs results afterward, it does not warn the user before transmitting potentially sensitive scheduling data, and the header comments do not disclose this privacy-impacting network action.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script prints per-event schedule items including start/end times and meeting subjects, which goes beyond the skill's stated purpose of free/busy and meeting-time discovery. This exposes potentially sensitive calendar metadata such as meeting topics and detailed attendance patterns, increasing privacy and data-minimization risk if the output is consumed by an agent or shown to unauthorized users.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The JSON output includes busySlots with exact start/end times, subject, and status for each calendar item, not merely availability summaries. Structured output is especially risky because downstream agents or logs can easily store, forward, or repurpose this detailed calendar data beyond the intended scheduling use case.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script reads long-lived Azure application credentials from a local config file or environment and then uses them to mint an app-only Microsoft Graph access token. In the context of a calendar-availability skill, exposing a general-purpose token acquisition helper increases the blast radius because anyone who can run the script or access its outputs may obtain reusable access to tenant data beyond the immediate user request.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script reads AZURE_CLIENT_SECRET from environment variables or a local config file and sends it in an HTTPS request to Azure AD. While the network call is part of token retrieval, the file lacks an explicit warning that sensitive credentials are being read from local storage and transmitted for authentication.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script writes the access token to a predictable temp-file location and also prints the raw token to stdout. Tokens exposed through terminal history, logs, process capture, shared temp directories, or downstream tooling can be replayed by another local user or service to access Microsoft Graph as the application.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Comments and usage guidance are written in Thai, which effectively forces a specific language for operators reading the script. The file does not offer an alternative language or explain that the skill is intentionally limited to a Thai-speaking environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script makes Graph API calls that retrieve and print directory data without any warning, consent flow, or disclosure that employee information is being enumerated and emitted as JSON for downstream agent use. In an agent setting, silent collection and structured output of names and emails increases the chance of overcollection, unnoticed propagation, and misuse by other components.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The default behavior lists up to 100 users when no search term is supplied, enabling bulk tenant enumeration without a clear scheduling need. Even if capped, this creates unnecessary disclosure of employee names and email addresses and can aid internal phishing, targeting, or broader account discovery.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code includes user-facing usage text and comments in Thai, and later emits Thai warning/output strings, indicating the skill is effectively localized to Thai only. Under the policy, forcing a specific language without user opt-in or clear justified locale scoping is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script persists Azure tenant ID, client ID, and especially the client secret to a file in the user's home directory, but only emits a generic success message and does not clearly warn the user that long-lived credentials are being stored on disk. Even with mode 0600, disk persistence increases exposure through backups, endpoint compromise, accidental sharing, or later misuse by other local processes, and this is particularly sensitive in a Microsoft Graph calendar skill because the secret can enable access to organizational calendar data.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.