Back to skill

Security audit

Inbox Cleanup

Security checks for vulnerabilities and agentic risk

Overview

This inbox-cleanup skill is mostly coherent, but live mode has real mailbox-loss and credential-safety concerns that users should review before installing.

Install only after reviewing the code and treating it as a high-impact mailbox tool. Use dry-run first, prefer archive rules over delete rules, populate leave_domains for banks, auth, receipts, legal, and account services, avoid running live while other mail clients may have messages marked deleted, and do not enable certificate-verification bypass except for a trusted local bridge such as 127.0.0.1 with an account-specific IMAP password you can revoke.

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
scripts/inbox_cleanup.py:78
Finding

Optional TLS Certificate Verification Bypass Exposes IMAP Credentials

Content
View full analysis
imaplib.IMAP4: """Connect and authenticate to IMAP server.""" ctx = ssl.create_default_context() if skip_cert_verify: ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE if starttls: mail = imaplib.IMAP4(host, port) mail.starttls(ssl_context=ctx) else: mail = imaplib.IMAP4_SSL(host, port, ssl_context=ctx) mail.login(user, password) return mail ``` The unsafe option is also explicitly documented in `SKILL.md`: ```bash IMAP_SKIP_CERT_VERIFY=true # true = accept self-signed cert (required for Proton Bridge) ``` ### Technical Analysis When `skip_cert_verify` is enabled, the script disables both certificate-chain validation and hostname verification. TLS may still encrypt the connection, but the client no longer verifies that it is communicating with the intended IMAP server. The script subsequently transmits the IMAP username and password through `mail.login(user, password)`. An attacker able to intercept, redirect, or control the configured IMAP endpoint can present an arbitrary certificate, have it accepted by the client, and receive the authentication exchange. Network access and transmission of IMAP credentials are necessary for the declared mailbox-cleanup functionality. However, accepting an unauthenticated server is not necessary except for a narrowly constrained local self-signed service. The current implementation allows the bypass with any configurable host, exceeding the minimum safe network privilege needed for the Skill. ### Attack Path 1. A user enables `IMAP_SKIP_CERT_VERIFY=true`, as documented for sel ...[truncated 1377 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/inbox_cleanup.py:219
Finding

Global IMAP EXPUNGE Can Permanently Delete Unrelated Messages

Content
View full analysis
int: if not messages: return 0 print(f"{'[DRY RUN] Would delete' if dry_run else 'Deleting'} {len(messages)} messages...") if dry_run: for m in messages[:5]: print(f" [{m['domain']}] {m['subject'][:70]}") if len(messages) > 5: print(f" ... and {len(messages) - 5} more") return len(messages) count = 0 for m in messages: uid = m["uid"] uid_b = uid.encode() if isinstance(uid, str) else uid mail.uid("STORE", uid_b, "+FLAGS", "\\Deleted") count += 1 mail.expunge() return count def apply_archive(mail: imaplib.IMAP4, messages: list[dict], archive_folder: str, dry_run: bool) -> int: if not messages: return 0 print(f"{'[DRY RUN] Would archive' if dry_run else 'Archiving'} {len(messages)} messages " f"to '{archive_folder}'...") if dry_run: for m in messages[:5]: print(f" [{m['domain']}] {m['subject'][:70]}") if len(messages) > 5: print(f" ... and {len(messages) - 5} more") return len(messages) count = 0 for m in messages: uid = m["uid"] uid_b = uid.encode() if isinstance(uid, str) else uid try: s, _ = mail.uid("COPY", uid_b, archive_folder) if s == "OK": mail.uid("STORE", uid_b, "+FLAGS", "\\Deleted") count += 1 else: print(f" COPY failed for UID {uid}: {s}") except Exception as e: print(f" Error archiving UID {uid}: {e}") if count: mail.expunge() return count ``` ### Technical Analysis The script correctly uses UID-b ...[truncated 2735 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The config explicitly states that matching domains will be 'permanently expunged' but does not present a prominent warning about irreversible data loss in the example users are expected to copy. Given this skill's purpose is bulk email triage, omission of a strong destructive-action warning materially increases the chance of accidental mass deletion of important messages.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill handles sensitive email operations and requires environment secrets like IMAP_PASSWORD, but it does not declare an explicit tool/permission scope for environment access and file read/write behavior. That omission weakens least-privilege controls and makes it harder for a runtime or reviewer to constrain what the skill may access, increasing the risk of secret exposure or unintended filesystem effects if the implementation is modified or abused.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The example configuration encourages hard deletion by domain using broad matching guidance and only minimal examples of exclusions. In an inbox-cleanup skill that performs bulk operations on IMAP UIDs, this can lead users to configure destructive rules that permanently remove legitimate mail from entire domains, especially for senders that mix transactional and important notifications.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.insecure_tls_verification

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/inbox_cleanup.py:315

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/inbox_cleanup.py:83