Back to skill

Security audit

Google Keep

Security checks for vulnerabilities and agentic risk

Overview

This Google Keep skill is purpose-built for note management, but it uses long-lived full-account Google tokens in ways that create meaningful credential-exposure risk.

Review this carefully before installing. Use only on a private, trusted machine; assume the master token is equivalent to a password; avoid pasting tokens into shell commands if possible; clear shell history after setup; keep the skill directory and backups private; and prefer a version that pins dependencies and uses a secure credential store or interactive secret prompt.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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

Error
Location
gkeep.py:457
Finding

Authentication Secrets Exposed Through Command-Line Arguments

Content
View full analysis
gkeep auth-master ``` ### Technical Analysis Both authentication flows require sensitive tokens to be supplied as positional command-line arguments. Command-line secrets may be recorded in shell history, terminal session logs, process-accounting systems, endpoint monitoring tools, or diagnostic bundles. Depending on the operating system and process visibility configuration, other local users or processes may also be able to inspect the argument vector while the command is running. This is particularly sensitive for `auth-master`, because the project documentation states that the master token does not expire and grants full access to the associated account. Although the application subsequently stores the token in a file with mode `0600`, those file permissions do not protect the original token while it is present in the command invocation. ### Attack Path 1. A user follows the documented setup instructions and executes `gkeep auth-master user@example.com ` ...[truncated 1182 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:10
Finding

Unpinned Security-Sensitive Third-Party Dependencies

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
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares shell, file read/write, and environment-related capabilities through its installation and usage instructions, but it does not explicitly scope or constrain those capabilities with permissions or allowed-tools metadata. This increases the blast radius of the skill because consumers cannot easily enforce least privilege or understand what execution surfaces are intended.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill intentionally creates persistent local state by installing packages into a virtual environment and, more importantly, by storing long-lived Google authentication material and cached note state in .config/. Because the documented master token provides full account access and does not expire, compromise of the workspace or skill directory could lead to durable unauthorized access to the user's Google account and note data.

Content

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

md
- id: venv
        kind: shell
        command: "cd \"$SKILL_DIR\" && uv venv .venv && .venv/bin/pip install gkeepapi gpsoauth"
        label: "Create venv and install gkeepapi + gpsoauth"
---

# Google Keep CLI Skill

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

gkeep auth-master <master_token>

text

Credentials are stored in `<skill-dir>/.config/` (chmod 600). The master token has full account access — treat it like a password. It does **not expire** (unlike standard OAuth refresh tokens).

## Commands

Tainted flow: 'EMAIL_FILE' from os.environ.get (line 28, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · gkeep.py (reported line 37)May include surrounding context.

python
def save_email(email):
    ensure_config_dir()
    with open(EMAIL_FILE, "w") as f:
        f.write(email)
    os.chmod(EMAIL_FILE, 0o600)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code writes the authentication token to disk in plaintext without prominent disclosure or use of secure secret storage. Even with 0600 permissions, plaintext local secrets are at risk from backups, misconfigured homes, malware, container volume exposure, or accidental path redirection, and here the token is a master token with substantial account impact.

Content

No source excerpt is available for this finding.

Tainted flow: 'TOKEN_FILE' from os.environ.get (line 26, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · gkeep.py (reported line 51)May include surrounding context.

python
def save_master_token(token):
    ensure_config_dir()
    with open(TOKEN_FILE, "w") as f:
        f.write(token)
    os.chmod(TOKEN_FILE, 0o600)

Tainted flow: 'STATE_FILE' from os.environ.get (line 27, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · gkeep.py (reported line 65)May include surrounding context.

python
def save_state(keep):
    ensure_config_dir()
    with open(STATE_FILE, "w") as f:
        json.dump(keep.dump(), f)
    os.chmod(STATE_FILE, 0o600)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill accepts an OAuth token, exchanges it for a Google master token, and stores that master token locally for reuse. A master token is a highly sensitive long-lived credential with broader account value than a normal app session token, so compromise of the host or config directory can expose access beyond simple note operations; this is especially dangerous because the skill context is a note-management CLI, making the credential scope disproportionate to the task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The cached state file contains serialized Keep state, which may include note content and metadata, and it is saved locally without explicit user disclosure. In a note-management tool this data is intrinsically sensitive, so silent persistence increases exposure through local compromise, backups, and shared or ephemeral environments.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.