Back to skill

Security audit

claw-mail

Security checks for vulnerabilities and agentic risk

Overview

This is a real email-management skill, but it should go to Review because it handles email credentials and content while allowing insecure token, webhook, transport, and state-file behavior.

Review this carefully before installing. Use only trusted configuration files, keep IMAP/SMTP TLS enabled, restrict OAuth token_uri and webhook URLs to trusted HTTPS providers, avoid shared or /tmp state files, and understand that rules can send, forward, reply to, move, archive, and expose metadata about emails.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib/oauth2.py:82
Finding

OAuth2 secrets can be transmitted to an arbitrary or plaintext token endpoint

Content
View full analysis
Any: """Create an OAuth2Manager if the config uses oauth2 auth.""" if cfg.get("auth") != "oauth2": return None oauth2_cfg = cfg.get("oauth2", {}) if not oauth2_cfg: return None from .oauth2 import OAuth2Manager return OAuth2Manager(oauth2_cfg) ``` ### Technical Analysis The OAuth2 refresh request includes the reusable refresh token and, when configured, the OAuth client secret. The destination is controlled entirely by `token_uri`; the implementation does not: - Require HTTPS. - Restrict the endpoint to an approved identity provider. - Reject loopback, private, link-local, or cloud metadata addresses. - Disable redirects or revalidate redirect destinations. Consequently, a malicious or compromised configuration can ...[truncated 1586 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lib/imap_client.py:159
Finding

Authentication credentials and email content can be transmitted without TLS

Content
View full analysis
None: if self.use_ssl: ctx = self._create_secure_context() self._connection = imaplib.IMAP4_SSL( self.host, self.port, ssl_context=ctx, timeout=self.timeout, ) else: self._connection = imaplib.IMAP4(self.host, self.port) self._connection.socket().settimeout(self.timeout) if self._oauth2: from .oauth2 import build_xoauth2_string auth_string = build_xoauth2_string( self.username, self._oauth2.access_token, ) self._connection.authenticate( "XOAUTH2", lambda _x: auth_string.encode("ascii"), ) else: self._connection.login(self.username, self.password) ``` The SMTP client has an equivalent downgrade path: ```python try: if self.use_tls: server = smtplib.SMTP(self.host, self.port) server.ehlo() ctx = self._create_secure_context() server.starttls(context=ctx) server.ehlo() else: server = smtplib.SMTP(self.host, self.port) if self._oauth2: from .oauth2 import build_xoauth2_string auth_string = build_xoauth2_string( self.username, self._oauth2.access_token, ) server.docmd("AUTH", "XOAUTH2 " + auth_string) elif self.username: server.login(self.username, self.password) ``` The downgrade is exposed through command-line options: ```python parser.add_argument("--imap-host", default="", help="IMAP server") parser.add_argument("--imap-port", type=int, default=993, help="IMAP port" ...[truncated 2385 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/lib/processor.py:178
Finding

Webhook rules allow SSRF and automatic disclosure of email metadata

Content
View full analysis
None: """POST a JSON payload to the webhook URL.""" msg = result.message payload = json.dumps({ "event": "email_rule_match", "message_id": msg.message_id, "subject": msg.subject, "sender": str(msg.sender) if msg.sender else "", "recipients": [str(r) for r in msg.recipients], "date": msg.date.isoformat() if msg.date else "", "account": msg.account, "mailbox": msg.mailbox, "matched_rules": result.matched_rules, "tags": result.tags, }).encode("utf-8") req = urllib.request.Request( url, data=payload, headers={"Content-Type": "application/json"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=10) as resp: result.webhook_results.append({ "url": url, "status": resp.status, "ok": 200 <= resp.status < 300, }) except Exception as exc: logger.warning("Webhook POST to %s failed: %s", url, exc) result.webhook_results.append({ "url": url, "status": 0, "ok": False, "error": str(exc), }) ``` ### Technical Analysis The webhook feature is declared by the Skill, so outbound notification traffic is expected. The implementation nevertheless accepts an unrestricted rule-controlled URL and automatically transmits private email metadata to it. There is no requirement for HTTPS and no validation against loopback, private, link-local, reserved, or cloud metadata destinations. `urllib.request.urlopen()` follows HTTP redirects by default, allowing an initially acceptable URL to redir ...[truncated 1455 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/heartbeat.py:162
Finding

Heartbeat shared-state handling exposes mailbox metadata and permits symlink overwrite or state tampering

Content
View full analysis
10000: seen_list = seen_list[-10000:] state["email_seen_ids"] = seen_list with open(args.state_file, "w") as f: json.dump(state, f, indent=2) ``` ### Technical Analysis The heartbeat state file is intended for persistent multi-agent coordination, but it is opened using ordinary `open()` operations without: - Enforcing mode `0600`. - Verifying file ownership. - Rejecting symbolic links. - Locking concurrent readers and writers. - Performing an atomic same-directory replacement. - Restricting the path to a private application-state director ...[truncated 1934 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (78)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad, end-to-end email management system with networked IMAP/SMTP functionality, account/security features, and automation capabilities. The supplied code chunk only implements local message composition: it accepts CLI arguments, builds a templated email payload, optionally reads attachment files from disk, and serializes the result as JSON. While composing emails is one subset of the declared functionality, the actual code here does not perform the primary claimed behaviors such as mailbox access, SMTP delivery, account management, credential handling, TLS/OAuth2, monitoring, or organizational workflows. Therefore the description materially overstates what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full-featured email management system spanning both IMAP and SMTP with many advanced capabilities. The supplied code chunk, however, only implements mail fetching over IMAP (or formatting messages from stdin) and outputting them as JSON or a CLI table. It supports multi-account configuration and direct credential use, which is consistent with part of the description, but the actual primary behavior in this chunk is much narrower than declared. Because the description claims many capabilities not represented by this code chunk, the description does not accurately represent what this supplied code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description covers a broad full-featured email management system spanning IMAP and SMTP, message composition/sending workflows, credential storage, automation, archival, and security features. The supplied code chunk is materially narrower: it is an IMAP retrieval and folder-management client. It does support some declared aspects, including hardened TLS 1.2+, OAuth2 authentication, IMAP IDLE push monitoring, folder organization, searching, reading, and appending messages. However, many prominent declared capabilities are absent from this code, especially SMTP sending, compose/reply/forward flows, secure credential storage, S/MIME, calendar invites, mail merge, webhook actions, archival, and broader multi-account orchestration. Because the actual code behavior is a subset with a different practical scope than the declared end-to-end skill description, this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a comprehensive email client/transport skill with many protocol, security, and account-management capabilities. The supplied code chunk is much narrower: it is a local rule engine for processing already-available EmailMessage objects and recording intended actions. It does not implement the core declared functionality such as IMAP/SMTP operations, authentication, credential storage, message transmission, monitoring, or advanced email features. It does include rule actions and webhook posting, which align partially with the description, but the actual behavior is only a small subset of the declared purpose. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description portrays a full-featured multi-account email management skill, but the supplied code chunk is narrowly scoped to SMTP email sending and MIME message assembly. Some declared items are partially reflected, such as hardened TLS 1.2+ configuration and OAuth2 SMTP authentication. However, the actual behavior lacks most of the described capabilities, especially all IMAP-related features and advanced workflow features. This is a description-behavior mismatch because the description materially overstates what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a comprehensive email client/transport skill with network-based IMAP/SMTP account management and many advanced mail features. The supplied code chunk does not implement those capabilities. Instead, it only ingests preexisting email messages from JSON/stdin, loads rule definitions, processes messages through a rule pipeline, and prints results. While rule-based email organization could be a supporting subcomponent of a mail-management skill, this chunk’s actual purpose is much narrower and materially different from the declared end-to-end email management functionality. Therefore this is a description-to-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code’s primary behavior is to retrieve one email by Message-ID from IMAP or stdin, optionally write attachments to disk, and render/output the message. That fits only a small subset of the declared description ('fetches'/'reads'). The declared purpose describes a much broader multi-account email management skill with many advanced capabilities not evidenced here. Most of that is over-declaration rather than a harmful undeclared action, but there is one concrete undeclared capability in this chunk: saving attachments to a local directory. Because the actual code chunk’s scope and primary purpose are materially narrower than the declared description, and it performs local file writes not stated in the description, this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description claims a broad, feature-rich email management skill covering both IMAP and SMTP operations, secure credential mechanisms, advanced delivery/authentication features, push monitoring, and multiple automation capabilities. The supplied code chunk does not implement that broad functionality. Instead, it is a narrowly scoped script whose main function is to collect messages (from stdin, direct IMAP connection, or configured account access) and group them into conversation threads based on email headers. While threading is one feature mentioned in the description, the actual code chunk's primary behavior is much narrower than the declared purpose. This is a description-behavior mismatch because the declared description materially overstates what this code does, and the code also exposes direct IMAP credential input via command-line flags without evidencing the declared security/authentication features in this chunk.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `references/TEMPLATES.md` | Available email templates and template variables |

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script builds a text/calendar MIME part but never actually sends that MIME message on either SMTP path; instead it constructs and sends a separate plain EmailMessage. This creates a security-relevant integrity gap between what operators believe is being transmitted and what is actually sent, which can silently break workflow controls, cause misleading audit expectations, and enable deceptive or malformed meeting-delivery behavior in automation.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'network' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The file invokes external binaries (op and security), which is a shell/process-execution capability that should be declared. Undeclared process execution reduces transparency and can expand the attack surface, especially in an email-management skill that handles valuable credentials and may run in automation contexts.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The file invokes external binaries (op and security), which is a shell/process-execution capability that should be declared. Undeclared process execution reduces transparency and can expand the attack surface, especially in an email-management skill that handles valuable credentials and may run in automation contexts.

Content

No source excerpt is available for this finding.

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 242)May include surrounding context.

md
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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 245)May include surrounding context.

md
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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 · assets/config.example.yaml (reported line 13)May include surrounding context.

yaml
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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 · assets/config.example.yaml (reported line 19)May include surrounding context.

yaml
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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 · assets/config.example.yaml (reported line 88)May include surrounding context.

yaml
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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 · assets/config.example.yaml (reported line 95)May include surrounding context.

yaml
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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 · references/REFERENCE.md (reported line 541)May include surrounding context.

md
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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/lib/account_manager.py (reported line 157)May include surrounding context.

python
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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/lib/account_manager.py (reported line 180)May include surrounding context.

python
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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/lib/credential_store.py (reported line 7)May include surrounding context.

python
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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/lib/credential_store.py (reported line 20)May include surrounding context.

python
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)

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/lib/credential_store.py (reported line 49)May include surrounding context.

python
them as plain text in config files.  Supported backends:

* **1Password CLI** (``op://vault/item/field``)
* **macOS Keychain** (``keychain://service/account``)
* **Environment variable** (``env://VAR_NAME``)
* **Plain text** — returned as-is (with a logged warning)