T05 · Unauthorized Access and Privilege Escalation
- Location
auth.js:12- Finding
Excessive and Unused Microsoft Graph OAuth Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a real Office 365 connector, but it grants broad Microsoft account access and has credential-handling and account-selection flaws that should be reviewed before use.
Review before installing. Use only with a dedicated, least-privilege Azure app if possible, avoid the raw token command, do not provide secrets on shared or logged shells, and prefer waiting for fixes that validate account names, remove unused scopes and stored client secrets, and add confirmations for send/cancel/remove actions.
auth.js:12Excessive and Unused Microsoft Graph OAuth Permissions
accounts.js:60Account Name Path Traversal Allows Token Operations Outside the Intended Directory
auth.js:27Explicitly Requested Missing Account Silently Falls Back to Legacy Credentials
accounts.js:239Client Secrets Are Exposed in Process Arguments and Stored Despite Being Unused
auth.js:320Authentication CLI Prints Microsoft Graph Bearer Tokens to Standard Output
Documenting a command that returns an access token materially increases credential exposure risk because bearer tokens can be copied, logged, pasted into shells, or harvested from terminal history and then used to access Microsoft Graph resources. In a multi-account context, this is more dangerous because one skill can expose tokens for several identities, broadening the blast radius if an operator or downstream tool mishandles them.
node auth.js login [--account=name] # Authenticate
node auth.js status [--account=name] # Check status
node auth.js token [--account=name] # Get access token
Referenced artifact was not completely inspected
See [Permissions Reference](references/permissions.md) for detailed information about what each permission allows.
Referenced artifact was not completely inspected
See [Permissions Reference](references/permissions.md) for detailed information about what each permission allows.
Referenced artifact was not completely inspected
Use the `accounts.js` CLI to manage:
The documented auth.js token command exposes a raw access token to the caller, which is a credential that can be reused to access Microsoft Graph on behalf of the user until expiry. In a multi-account skill with mail, calendar, and contacts scopes, token disclosure materially increases risk of account takeover of delegated API access and downstream data exfiltration or manipulation.
node auth.js login [--account=name] # Authenticate
node auth.js status [--account=name] # Check status
node auth.js token [--account=name] # Get access token
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}
/**
* Refresh access token
*/
async function refreshAccessToken(refreshToken, accountConfig) {
const authority = `https://login.microsoftonline.com/${accountConfig.tenantId}`;
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}
/**
* Refresh access token
*/
async function refreshAccessToken(refreshToken, accountConfig) {
const authority = `https://login.microsoftonline.com/${accountConfig.tenantId}`;
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}
/**
* Refresh access token
*/
async function refreshAccessToken(refreshToken, accountConfig) {
const authority = `https://login.microsoftonline.com/${accountConfig.tenantId}`;
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
A: No. This skill only requests email, calendar, and contact permissions. File access requires separate permissions (Files.Read, Files.ReadWrite, etc.).
**Q: How long do tokens last?**
A: Access tokens expire after 1 hour. Refresh tokens typically last 90 days but are automatically refreshed as long as you use the app regularly.
**Q: Is this secure?**
A: When configured properly, yes. The OAuth 2.0 protocol is industry-standard and secure. Follow the security best practices in this document and the setup guide.
The markdown documents node accounts.js remove <name> and notes that it deletes account configuration and authentication tokens, but it does not warn users about the irreversible impact or recommend confirmation/backup steps. Because this operation affects stored credentials and account state, the skill description should clearly disclose the risk before users run it.
The command reference includes node cancel-event.js <event-id> but provides no warning that invoking it may cancel a calendar event and potentially notify participants. This is a destructive or hard-to-reverse action affecting external users, so the markdown should disclose that consequence.
The skill documents use of environment variables for Azure tenant/client credentials but does not declare an explicit tool scope such as permissions or allowed-tools. That omission weakens reviewability and policy enforcement because consumers cannot easily tell that the skill expects access to sensitive configuration and authentication material.
The capability list includes destructive actions such as deleting messages, updating or deleting calendar events, and creating/updating/deleting contacts without prominent safety warnings or confirmation guidance. In an agent context, this increases the chance of accidental data loss or unauthorized modification if the skill is invoked incorrectly or by a compromised workflow.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
### Email Permissions
- `Mail.Read` - Read user email
- `Mail.ReadWrite` - Read and write access to user email
- `Mail.Send` - Send email as the user
### Calendar Permissions
The code stores the Azure client secret directly in a local JSON config file under the user's home directory. Although the file is written with mode 0600, persisting long-lived credentials to disk increases the risk of secret exposure through local compromise, backups, or accidental disclosure, and the CLI does not clearly warn the user that the secret will be stored.
The removeAccount function unlinks the token file and removes the account configuration, which is a destructive operation affecting local authentication state. While the CLI prints a success message afterward, there is no confirmation prompt or pre-action warning before deletion occurs.
The legacy import flow reads sensitive Azure credentials from environment variables and then saves them into the local accounts configuration, converting ephemeral secrets into persisted plaintext secrets. This broadens exposure without a clear warning to the user and can surprise operators who expected the credentials to remain only in process environment scope.
The CLI token command prints a live Microsoft Graph access token directly to stdout. In practice, stdout is often captured by shell history, logs, CI systems, terminal recorders, or parent processes, so this can unintentionally disclose credentials that grant mailbox, calendar, and contacts access.
This code fetches personal calendar information from Microsoft Graph and prints event details including subject, location, organizer, and attendees to stdout. While the network access and output behavior are visible in code, there is no user-facing warning or disclosure that potentially sensitive calendar data will be retrieved from a remote service and exposed in terminal output.
The script prints email subjects, senders, timestamps, and body previews directly to stdout without any confirmation, redaction, or warning. In a connector handling Microsoft 365 mailbox data, this can expose sensitive message contents and metadata to terminal logs, shell history workflows, CI logs, or other observers with access to the execution environment.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
3. Confirm you're in the correct directory (top-right corner)
- If managing multiple tenants, switch to the correct one
## Step 2: Create App Registration
1. In Azure Portal, search for "App registrations" in the top search bar
2. Click **+ New registration**
The guide instructs users to grant a broad set of Microsoft Graph delegated permissions covering full read/write access to mail, calendar, and contacts plus offline refresh capability. In a setup guide for an integration this may be functionally motivated, but it still meaningfully expands the blast radius if the skill, stored tokens, or host are compromised, and the guide does not prominently explain that these scopes allow ongoing access to highly sensitive user data.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
**⚠️ Security note:**
- Client secrets are sensitive - treat them like passwords
- Don't commit secrets to version control
- Restrict file permissions: `chmod 600 ~/.openclaw/openclaw.json`
## Step 9: First Authentication
The guide shows how to send email from a specific Office 365 account, but it does not include any warning that the command will transmit a real message from the chosen identity. For a multi-account skill, a brief disclosure is important to help users avoid sending mail from the wrong account.
The event time formatting is forced to use the 'en-US' locale, and other date displays later in the file also use 'en-US'. This imposes a specific language/locale behavior without giving the user a choice or documenting that the skill is intentionally U.S.-locale-specific.
No suspicious patterns detected.