Back to skill

Security audit

gmail-checker

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Gmail helper, but it needs Review because it can send, read, and modify email using powerful Gmail credentials without enough confirmation, scoping, or credential-safety guidance.

Install only if you are comfortable giving the skill access to send, read, and modify your Gmail. Use the narrowest OAuth scopes you can, avoid long-lived refresh tokens unless necessary, keep tokens out of prompts and logs, and require manual confirmation before any send, reply, label change, or bulk mailbox action.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:51
Finding
OAuth Credentials Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 51-55 **Vulnerability Type**: OAuth secret exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash GMAIL_ACCESS_TOKEN=$(curl -s -X POST "https://oauth2.googleapis.com/token" \ -d "client_id=$GMAIL_CLIENT_ID" \ -d "client_secret=$GMAIL_CLIENT_SECRET" \ -d "refresh_token=$GMAIL_REFRESH_TOKEN" \ -d "grant_type=refresh_token" | jq -r '.access_token') ``` ### Technical Analysis The shell expands `GMAIL_CLIENT_ID`, `GMAIL_CLIENT_SECRET`, and `GMAIL_REFRESH_TOKEN` before starting `curl`. Consequently, the expanded secrets are passed as command-line arguments. Although the credentials are transmitted over HTTPS to Google's legitimate OAuth endpoint, command-line arguments may be exposed through local process inspection, execution tracing, diagnostic tooling, audit systems, or logs that record expanded commands. A refresh token is particularly sensitive because it is long-lived and can be exchanged repeatedly for access tokens until revoked. The network transfer itself is necessary for OAuth token refresh. The vulnerability is the mechanism used to supply the credentials to `curl`, not the use of Google's OAuth service. ### Attack Path 1. The Skill refreshes the Gmail access token using the documented command. 2. A local process, monitoring agent, or user with sufficient process-inspection privileges observes the active `curl` command or captures an execution trace. 3. The expanded client secret and refresh token are recovered from the command-line arguments. 4. The attacker submits the stolen values to `https://oauth2.googleapis.com/token`. 5. Google returns an access token if the credentials remain valid. 6. The attacker uses that token to access Gmail operations permitted by the OAuth grants. This path requires local process, telemetry, tracing, or command-logging visibility; the Skill does not independently transmit credentials to an untrusted dom ...[truncated 574 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Avoid placing client secrets and refresh tokens directly in command-line arguments. - Provide the request body through standard input so secrets are not exposed in `curl` process arguments. For example: ```bash TOKEN_RESPONSE=$( printf '%s' \ "client_id=$(printf '%s' "$GMAIL_CLIENT_ID" | jq -sRr @uri)&client_secret=$(printf '%s' "$GMAIL_CLIENT_SECRET" | jq -sRr @uri)&refresh_token=$(printf '%s' "$GMAIL_REFRESH_TOKEN" | jq -sRr @uri)&grant_type=refresh_token" | curl --silent --show-error --fail \ -X POST \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-binary @- \ "https://oauth2.googleapis.com/token" ) GMAIL_ACCESS_TOKEN=$(printf '%s' "$TOKEN_RESPONSE" | jq -er '.access_token') ``` - Disable shell tracing around credential-processing commands and ensure secrets are never written to logs. - Validate that all required environment variables are present before attempting a refresh. - Use `curl --fail --show-error` and `jq -e` so authentication errors cannot silently produce an invalid token. - Keep credential-bearing environment variables available only to the Skill process and avoid exposing them to unrelated child processes. - Revoke and rotate the refresh token and client secret if process telemetry or command logs may already have captured them. ]]>

T05 · Unauthorized Access and Privilege Escalation

Note
Location
SKILL.md:270
Finding
Overly Broad Google Network Policy Exceeds Runtime Requirements<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 270-288 **Vulnerability Type**: Excessive network permissions and insufficient endpoint restriction **Risk Level**: Low ### Vulnerable Code ```yaml network_policies: google_gmail: name: google_gmail endpoints: - host: gmail.googleapis.com port: 443 protocol: rest enforcement: enforce tls: terminate rules: - allow: { method: GET, path: "/**" } - allow: { method: POST, path: "/**" } - host: oauth2.googleapis.com port: 443 protocol: rest enforcement: enforce tls: terminate rules: - allow: { method: POST, path: "/token" } - host: accounts.google.com port: 443 protocol: rest enforcement: enforce tls: terminate rules: - allow: { method: GET, path: "/**" } - allow: { method: POST, path: "/**" } ``` ### Technical Analysis The policy permits GET and POST requests to every path on `gmail.googleapis.com` and `accounts.google.com`. The documented runtime implementation only requires specific Gmail API paths and the OAuth token endpoint. No runtime command in the audited file demonstrates a need for unrestricted access to `accounts.google.com`. Communication with Gmail and the OAuth token endpoint is essential to the declared functionality. However, wildcard path access exceeds the minimum network privileges demonstrated by the Skill. This increases the API surface available if untrusted email content, a malicious user request, or another compromise causes the Agent to issue unintended requests. OAuth scopes and Google-side authorization continue to restrict available Gmail operations, so the network policy does not independently grant account privileges. Nevertheless, it removes a useful sandbox-level defense that could otherwise prevent access to undocumented endpoints. ### Attack Path 1. The sand ...[truncated 1295 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `accounts.google.com` from the runtime policy unless an implemented interactive OAuth flow specifically requires it. - Keep OAuth refresh access restricted to: ```yaml - host: oauth2.googleapis.com port: 443 protocol: rest enforcement: enforce tls: terminate rules: - allow: { method: POST, path: "/token" } ``` - Replace Gmail wildcard rules with the narrowest paths needed for implemented features, such as the relevant resources under: - `/gmail/v1/users/me/messages` - `/gmail/v1/users/me/messages/**` - `/gmail/v1/users/me/drafts` - `/gmail/v1/users/me/drafts/**` - `/gmail/v1/users/me/labels` - `/gmail/v1/users/me/labels/**` - Restrict methods per endpoint and operation instead of allowing both GET and POST everywhere. - Separate setup-time browser authorization permissions from runtime Gmail API permissions. - Maintain distinct policy profiles for read-only, send-only, and mailbox-modification use cases where the sandbox supports per-invocation policies. - Test the reduced policy against every documented operation to ensure functionality without restoring global wildcard access. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Credential Access

High
Category
Privilege Escalation
Content
## Setup

### Option 1: OAuth2 Access Token (recommended)

1. Create OAuth2 credentials at https://console.cloud.google.com/apis/credentials
2. Enable the Gmail API at https://console.cloud.google.com/apis/library/gmail.googleapis.com
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
1. Create OAuth2 credentials at https://console.cloud.google.com/apis/credentials
2. Enable the Gmail API at https://console.cloud.google.com/apis/library/gmail.googleapis.com
3. Obtain an access token via OAuth2 flow with scopes:
   - `https://www.googleapis.com/auth/gmail.send`
   - `https://www.googleapis.com/auth/gmail.readonly`
   - `https://www.googleapis.com/auth/gmail.modify`
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
1. Create OAuth2 credentials at https://console.cloud.google.com/apis/credentials
2. Enable the Gmail API at https://console.cloud.google.com/apis/library/gmail.googleapis.com
3. Obtain an access token via OAuth2 flow with scopes:
   - `https://www.googleapis.com/auth/gmail.send`
   - `https://www.googleapis.com/auth/gmail.readonly`
   - `https://www.googleapis.com/auth/gmail.modify`
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- Gmail API rate limit: 250 quota units per second per user.
- Sending has a daily limit of 2,000 messages for Google Workspace, 500 for free Gmail.
- Access tokens expire after ~1 hour. Use refresh token flow for long-running sessions.
- Attachments require multipart MIME encoding — for large files, use the resumable upload endpoint.

## Examples
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill is user-invocable and performs high-impact actions such as sending mail, replying, drafting, and modifying labels, yet it lacks an upfront requirement for confirmation before state-changing operations. That makes accidental or socially engineered email actions more likely, especially when prompts are ambiguous or maliciously crafted.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The setup section instructs users to provide powerful Gmail credentials and refresh tokens but does not warn about their sensitivity, scope minimization, storage handling, or the risks of long-lived tokens. This increases the chance of insecure deployment and overprivileged access to a mailbox.

External Transmission

Medium
Category
Data Exfiltration
Content
All API calls use Bearer auth:

```bash
curl -s -H "Authorization: Bearer $GMAIL_ACCESS_TOKEN" \
  "https://gmail.googleapis.com/gmail/v1/users/me/..."
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill expands from Gmail operations into arbitrary web searching and page fetching, which is outside the declared Gmail-only scope. That creates unnecessary data egress and prompt-surface expansion: email content or user-provided topics could be sent to third-party sites, and fetched content could influence generated emails in unsafe ways.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
A Gmail management skill does not need general web browsing to fulfill its core purpose, so this capability materially broadens attack surface without justification. It enables unintended external transmission of user prompts or email-derived content to arbitrary websites and introduces untrusted content into downstream email composition.

External Transmission

Medium
Category
Data Exfiltration
Content
ENCODED=$(echo -n "$RAW_MESSAGE" | base64 -w 0 | tr '+/' '-_' | tr -d '=')

# Send
curl -s -X POST \
  -H "Authorization: Bearer $GMAIL_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
ENCODED=$(echo -n "$RAW_MESSAGE" | base64 -w 0 | tr '+/' '-_' | tr -d '=')

# Send
curl -s -X POST \
  -H "Authorization: Bearer $GMAIL_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
ENCODED=$(echo -n "$RAW_MESSAGE" | base64 -w 0 | tr '+/' '-_' | tr -d '=')

curl -s -X POST \
  -H "Authorization: Bearer $GMAIL_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  "https://gmail.googleapis.com/gmail/v1/users/me/drafts" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"https://gmail.googleapis.com/gmail/v1/users/me/labels" | jq '.labels[] | {name, id}'

# Add label to a message
curl -s -X POST \
  -H "Authorization: Bearer $GMAIL_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  "https://gmail.googleapis.com/gmail/v1/users/me/messages/{MESSAGE_ID}/modify" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Low
Confidence
85% confidence
Finding
The proposed network policy grants broad GET/POST access to `accounts.google.com`, but the documented flows only require Gmail API and token refresh endpoints. Overbroad egress permissions increase the chance of unintended authentication interactions, data leakage, or abuse if the skill or surrounding agent is prompted to access unrelated Google account pages.

Static analysis

No suspicious patterns detected.