Back to skill

Security audit

Google Docs Skill

Security checks for vulnerabilities and agentic risk

Overview

This Google Docs skill is mostly coherent, but its examples expose live OAuth tokens and under-warn about document-changing API access.

Install only if you are comfortable granting Google Docs API access. Do not run the token examples as written in shared terminals, logs, CI, or agent transcripts; avoid printing refresh or access tokens, store credentials in a proper secret store, and revoke any token that may have been exposed.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:83
Finding

OAuth Access and Refresh Tokens Exposed in Console Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:42
Finding

OAuth Callback Is Not Correlated with State and Does Not Use PKCE

Content
View full analysis

Authorization successful!

You can close this window.

') server = HTTPServer(('localhost', 8080), OAuthHandler) server.handle_request() # Step 3: Exchange code for tokens if auth_code: data = urllib.parse.urlencode({ 'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code' }).encode() req = urllib.request.Request('https://oauth2.googleapis.com/token', data=data) ``` ### Technical Analysis The authorization request does not include a cryptographically random OAuth `state` value, and the callback handler does not validate that the response corresponds to the authorization request initiated by the script. It accepts the first `code` query parameter received by the local HTTP server. The flow also omits Proof Key for Code Exchange (PKCE). PKCE binds the authorization code to a verifier held by the initiating client and ...[truncated 1980 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (13)

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

This example prints live OAuth refresh and access tokens directly, exposing secrets that can be reused to access the user's Google Docs data. A leaked refresh token is especially dangerous because it can be exchanged for fresh access tokens long after the initial session ends.

Content

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

response = json.load(urllib.request.urlopen(req))

text
print(f"\nRefresh Token: {response['refresh_token']}")
print(f"Access Token: {response['access_token']}")
print(f"\nSet your refresh token:")
print(f"export GOOGLE_REFRESH_TOKEN=\"{response['refresh_token']}\"")
text

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 · SKILL.md (reported line 92)May include surrounding context.

print(f"export GOOGLE_REFRESH_TOKEN="{response['refresh_token']}"")

text

### Getting Access Token

Before making API calls, get a fresh access token:

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 · SKILL.md (reported line 94)May include surrounding context.

Getting Access Token

Before making API calls, get a fresh access token:

python
import urllib.request

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 · SKILL.md (reported line 103)May include surrounding context.

Getting Access Token

Before making API calls, get a fresh access token:

python
import urllib.request

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 · SKILL.md (reported line 126)May include surrounding context.

Getting Access Token

Before making API calls, get a fresh access token:

python
import urllib.request

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 · SKILL.md (reported line 139)May include surrounding context.

Getting Access Token

Before making API calls, get a fresh access token:

python
import urllib.request

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 · SKILL.md (reported line 350)May include surrounding context.

Getting Access Token

Before making API calls, get a fresh access token:

python
import urllib.request

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 · SKILL.md (reported line 455)May include surrounding context.

Getting Access Token

Before making API calls, get a fresh access token:

python
import urllib.request

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

This example prints the access token after retrieval, making it easy to leak via logs or console history. Even short-lived access tokens can grant unauthorized document access during their validity period.

Content

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

Store for reuse

access_token = get_access_token() print(f"Access Token: {access_token}")

text

## Base URL

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 · SKILL.md (reported line 461)May include surrounding context.

| 429 | Rate Limited - Too many requests |

Token Refresh

Access tokens expire after 1 hour. If you get a 401 error, refresh the token:

python
try:

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 · SKILL.md (reported line 481)May include surrounding context.

md
## Best Practices

1. **Token Management**
   - Cache access tokens (valid for 1 hour)
   - Store refresh token securely
   - Implement automatic token refresh

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill describes creating, reading, and modifying Google Docs content but does not clearly warn that document data will be transmitted to Google and that API operations can alter remote documents. This omission can mislead users about data handling and action side effects, increasing the chance of unintended disclosure or destructive changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation explicitly prints both the refresh token and access token to stdout, which can expose credentials through terminal history, logs, screen recording, or shared sessions. Because refresh tokens enable ongoing API access, this creates a realistic credential leakage risk even though it appears intended as a convenience example.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:116