Back to skill

Security audit

gmail-cleanup

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Gmail triage and cleanup helper with approval and dry-run gates for mailbox changes, though it still handles sensitive email access and credentials.

Install only if you are comfortable granting this skill access to your Gmail through gog and sending approval digests to your configured Telegram target. Keep GOG_KEYRING_PASSWORD ephemeral, review pending/approved action files before applying, leave dry-run and send gates enabled unless intentionally changing mail, and use a narrow Gmail query plus modest action caps.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The supplied code does not implement cleanup actions; it performs a read-only scan of Gmail inbox messages since the last run and updates scan state. While inbox triage/scanning is consistent with part of the description, the prominent declared behaviors—approval on Telegram, drafting replies, and archive/trash after approval—are absent from this chunk. Also, the code clearly depends on Gmail-related credentials and local state/config files, which is inconsistent with the empty declared permissions list. This is therefore a description/behavior mismatch for the provided code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose centers on Gmail cleanup actions with Telegram used as an approval mechanism. The actual code chunk is only a notification sender: it reads text and sends it to Telegram through OpenClaw. It does not access Gmail, classify emails, draft replies, or enforce approval before mailbox actions. While Telegram notification could be a supporting component of the broader skill, this specific chunk performs an undeclared messaging capability and does not implement the described primary behavior, so the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The supplied code chunk is a read-only scanning component, not a full approval-gated cleanup skill. It accesses Gmail data by running gog gmail search and gog gmail get, extracts message metadata/body snippets, and writes results to state/gmail-cleanup/latest.json. The script explicitly states and enforces that it performs no mutations. There is no code for sending Telegram messages, waiting for approval, drafting replies, or archiving/trashing emails. This is a material mismatch because the declared description presents a user-approved inbox cleanup system with reply drafting and post-approval actions, while the actual code only gathers candidate messages for later classification. Additionally, the declared permissions are empty, but the code clearly reads Gmail content, which is an accessed resource inconsistent with that declaration.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

This duplicate finding points to the same credential-handling issue: the workflow depends on access to a sensitive keyring secret during execution. In a skill that can invoke shell commands and external tools, any unexpected subprocess, debug output, or misconfiguration can leak that credential and broaden compromise beyond this skill.

Content

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

than typed in plaintext:

bash
export GOG_KEYRING_PASSWORD='<your gog keyring password>'   # current session only
# or, sourced from a secret manager:
export GOG_KEYRING_PASSWORD="$(pass show gog-keyring)"      # current session only

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

This duplicate finding points to the same credential-handling issue: the workflow depends on access to a sensitive keyring secret during execution. In a skill that can invoke shell commands and external tools, any unexpected subprocess, debug output, or misconfiguration can leak that credential and broaden compromise beyond this skill.

Content

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

than typed in plaintext:

bash
export GOG_KEYRING_PASSWORD='<your gog keyring password>'   # current session only
# or, sourced from a secret manager:
export GOG_KEYRING_PASSWORD="$(pass show gog-keyring)"      # current session only

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

This is the same underlying secret-handling weakness at a second matched token. The context is not overtly malicious, but the combination of email access, shell execution, and ambient credentials increases the blast radius if the password is exposed.

Content

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

bash
   export GOG_KEYRING_PASSWORD='<your gog keyring password>'   # current session only
   # or, sourced from a secret manager:
   export GOG_KEYRING_PASSWORD="$(pass show gog-keyring)"      # current session only

Do not commit the secret or persist it in shell rc; prefer a secret manager

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

This is the same underlying secret-handling weakness at a second matched token. The context is not overtly malicious, but the combination of email access, shell execution, and ambient credentials increases the blast radius if the password is exposed.

Content

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

bash
   export GOG_KEYRING_PASSWORD='<your gog keyring password>'   # current session only
   # or, sourced from a secret manager:
   export GOG_KEYRING_PASSWORD="$(pass show gog-keyring)"      # current session only

Do not commit the secret or persist it in shell rc; prefer a secret manager

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/cleanup-execute.py (reported line 18)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/cleanup-execute.py (reported line 68)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/cleanup-execute.py (reported line 70)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/delta-scan.sh (reported line 10)May include surrounding context.

sh
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/delta-scan.sh (reported line 12)May include surrounding context.

sh
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/delta-scan.sh (reported line 22)May include surrounding context.

sh
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/delta-scan.sh (reported line 23)May include surrounding context.

sh
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/triage-scan.py (reported line 8)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/triage-scan.py (reported line 18)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/triage-scan.py (reported line 45)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

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/triage-scan.py (reported line 47)May include surrounding context.

python
JSON file (state/gmail-cleanup/latest.json) for the agent to classify.
Performs NO mutations.

Credentials: read from the GOG_KEYRING_PASSWORD environment variable ONLY. This
script never reads credential files. The Workspace CLI is invoked as `gog` from
PATH; no executable override is honored.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill declares no explicit tool scope or permissions despite describing capabilities that require shell execution, filesystem writes, network access, and access to environment secrets. That mismatch weakens containment and review because a runtime may grant broader-than-expected powers to a skill handling email and Telegram actions.

Content

No source excerpt is available for this finding.

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

Medium
Category
Data Flow
Confidence
85% confidence
Finding

The audit log path is derived from GMAIL_CLEANUP_STATE, which is environment-controlled, and the script appends to that path without validating that it remains within an expected directory or is not a symlink. If an attacker can influence the environment in the execution context, they may redirect writes to unintended files, causing log forgery or clobbering of arbitrary writable files.

Content

Scanner excerpt · scripts/cleanup-execute.py (reported line 96)May include surrounding context.

python
def record(line):
    with open(audit, "a") as f:
        f.write(line + "\n")
    print(line)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cleanup-execute.py (reported line 110)May include surrounding context.

python
delay = 2.0
    r = None
    for attempt in range(retries + 1):
        r = subprocess.run(base, capture_output=True, text=True)
        out = (r.stdout + r.stderr).strip()
        if r.returncode == 0 or not any(h in out.lower() for h in RATE_HINTS):
            return r.returncode, out

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/triage-scan.py (reported line 80)May include surrounding context.

python
delay = 2.0
    last = ""
    for attempt in range(retries + 1):
        r = subprocess.run([GOG, *args, "-a", acc, "-j"], capture_output=True, text=True)
        out, err = r.stdout, r.stderr
        if r.returncode == 0:
            return json.loads(out)

Tainted flow: 'acc' from open (line 56, file read) → subprocess.run (code execution)

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 · scripts/triage-scan.py (reported line 80)May include surrounding context.

python
delay = 2.0
    last = ""
    for attempt in range(retries + 1):
        r = subprocess.run([GOG, *args, "-a", acc, "-j"], capture_output=True, text=True)
        out, err = r.stdout, r.stderr
        if r.returncode == 0:
            return json.loads(out)

Tainted flow: 'STATE' from os.environ.get (line 29, 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 · scripts/triage-scan.py (reported line 164)May include surrounding context.

python
"skipped": skipped,
    "candidates": candidates,
}
with open(os.path.join(STATE, "latest.json"), "w") as f:
    json.dump(out, f, indent=2)
print(
    f"triage-scan: {len(candidates)} candidates ({skipped} skipped) "

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The comment says 'Credentials: GOG_KEYRING_PASSWORD from the environment ONLY,' which strongly suggests environment-only configuration, but the script then loads operational configuration from a JSON file at L18, L26, L37, and L41. While this is not a dangerous contradiction by itself, the inline documentation overstates the extent to which runtime inputs are environment-only.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.