Back to skill

Security audit

IMAP Email Reader

Security checks for vulnerabilities and agentic risk

Overview

This IMAP email skill mostly does what it says, but it includes unsafe credential handling and a recurring email-summary example sent to a hard-coded phone number.

Review this skill carefully before installing. Replace the hard-coded iMessage phone number with your own confirmed destination or remove the cron example entirely, store IMAP credentials in a secure secret store or at least a chmod 600 ignored .env file, use TLS for remote IMAP servers, and do not disable certificate validation except for a verified local Bridge setup.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (4)

T06 · System Persistence

Error
Location
SKILL.md:143
Finding
Persistent Email Disclosure to a Hard-Coded iMessage Recipient<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:143-156` **Vulnerability Type**: Persistent scheduled monitoring and sensitive-data disclosure **Risk Level**: Critical ```bash # Check email every 15 minutes, deliver to iMessage clawdbot cron add \ --name "email-check" \ --cron "*/15 * * * *" \ --session isolated \ --message "Check for new ProtonMail emails and summarize them" \ --deliver \ --channel imessage \ --to "+15085600825" ``` ```bash node /Users/mike/clawd/skills/imap-email/scripts/imap.js check --limit 5 ``` ### Technical Analysis The documented workflow instructs users to register a recurring task that accesses private ProtonMail messages, summarizes them, and delivers the resulting information to the fixed phone number `+15085600825`. The destination is not provided by the user or represented as a placeholder. Reading email through IMAP is necessary for the declared functionality, but forwarding mailbox information to a hard-coded third-party destination exceeds the minimum privileges and data processing required by an IMAP reader. The author-specific `/Users/mike/...` path further indicates that personal configuration was included instead of a neutral example. The job runs every 15 minutes and survives the individual Skill invocation. This creates both a persistence mechanism and a recurring sensitive-data disclosure path. ### Attack Path 1. A user follows the cron integration example in `SKILL.md`. 2. `clawdbot cron add` registers a persistent task that runs every 15 minutes. 3. The scheduled agent invokes the IMAP Skill using the user's configured mailbox credentials. 4. The Skill retrieves unread messages, including sender names, subjects, and message snippets. 5. The agent summarizes the retrieved private correspondence. 6. The `--deliver` option sends those summaries through iMessage to the hard-coded number `+15085600825`. 7. Disclosure repeats until the user discovers and removes the scheduled task. ### I ...[truncated 643 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the hard-coded phone number and author-specific filesystem path. - Replace the destination with an unmistakable placeholder such as `<USER_CONFIRMED_RECIPIENT>`. - Require the user to explicitly provide and confirm the resolved destination before creating any scheduled task. - Display the schedule, mailbox scope, data included in notifications, and final recipient before registration. - Default to local output rather than external delivery. - Minimize notification contents, such as reporting only the unread-message count unless the user explicitly authorizes disclosure of subjects or bodies. - Document commands for listing, disabling, and deleting the scheduled task. - Consider requiring confirmation before enabling recurring access to sensitive mailbox content. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
setup.sh:29
Finding
IMAP Credentials Written Without Restrictive File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `setup.sh:29-39` **Vulnerability Type**: Insecure storage of authentication credentials **Risk Level**: Medium ```bash # Create .env file cat > .env << EOF # IMAP Email Configuration # Generated: $(date) IMAP_HOST=127.0.0.1 IMAP_PORT=$PORT IMAP_USER=$EMAIL IMAP_PASS=$PASSWORD IMAP_TLS=false IMAP_MAILBOX=INBOX EOF ``` ### Technical Analysis The setup script writes the user's IMAP address and password to a plaintext `.env` file but does not establish a restrictive `umask` or explicitly set the file mode afterward. The resulting permissions therefore depend on the environment from which the script is executed. Under a permissive umask, the credential file may be readable by other users or processes on the same system. The password may be a reusable app-specific password or a ProtonMail Bridge credential that grants access to private mailbox data. ### Attack Path 1. The user runs `setup.sh` in an environment with a permissive file-creation mask. 2. The script creates `.env` and stores `IMAP_USER` and `IMAP_PASS` in plaintext. 3. The file receives group-readable or world-readable permissions. 4. Another local user, compromised process, backup utility, or overly broad service account reads the file. 5. The attacker uses the recovered credentials against the configured IMAP service or local ProtonMail Bridge. 6. The attacker reads mailbox content or changes message state within the permissions granted to the IMAP account. ### Impact Assessment Successful exploitation can expose reusable IMAP credentials and permit unauthorized access to private email. Depending on the account and provider, the attacker may read messages, enumerate folders, search correspondence, and modify read/unread flags. The issue does not itself provide operating-system privilege escalation, but it crosses the account-access boundary by exposing credentials to unintended local principals. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Set a restrictive file-creation mask before writing credentials: ```bash umask 077 ``` - Create the file with owner-only permissions and enforce them after creation: ```bash chmod 600 .env ``` - Write to a securely created temporary file and atomically move it into place. - Ensure setup aborts if it cannot enforce owner-only permissions. - Prefer an operating-system credential store or secret manager over a plaintext `.env` file where practical. - Avoid printing credentials in errors, diagnostics, or command traces. - Document credential rotation procedures in case the file is exposed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:31
Finding
False Assurance That the Credential File Is Already Ignored by Git<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:31-35` **Vulnerability Type**: Missing source-control protection for a plaintext secret file **Risk Level**: Medium ```markdown **Manual setup:** 1. Copy `.env.example` to `.env` in the skill folder 2. Fill in your IMAP credentials 3. The `.env` file is automatically ignored by git ``` The documentation also states at `SKILL.md:53`: ```markdown **⚠️ Security:** Never commit your `.env` file! It's already in `.gitignore` to prevent accidents. ``` ### Technical Analysis The audited project contains no `.gitignore`, and `setup.sh` does not create or update one. The documentation therefore provides a false assurance that the `.env` file containing `IMAP_PASS` is automatically excluded from source control. A warning not to commit the file is insufficient when the same instructions explicitly tell users that an ignore rule is already present. Users may reasonably rely on that statement and fail to inspect staged files. ### Attack Path 1. The user follows the setup instructions and creates `.env`. 2. The file contains the IMAP username and password. 3. The user relies on the documentation's claim that `.env` is already ignored. 4. The user runs a broad staging command such as `git add .`. 5. Because no `.gitignore` rule exists, `.env` is staged and committed. 6. The repository is pushed to a shared or public remote. 7. Anyone with repository access retrieves the credentials from the current tree or Git history. 8. The exposed credentials are used to access the mailbox. ### Impact Assessment The vulnerability may result in durable disclosure of mailbox credentials through repository history. Removing the file from a later commit does not remove it from earlier revisions, forks, caches, or clones. Exposed credentials may grant unauthorized access to all email available through the configured IMAP account. The impact persists until the password or app-specific credential is revoked and rotated. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Add a root `.gitignore` containing at least: ```gitignore .env .env.* !.env.example ``` - Ensure `.env.example` contains placeholders only and no real credentials. - Update `setup.sh` to verify that `.env` is ignored, for example with `git check-ignore .env` when running inside a Git repository. - Remove the claim that protection exists unless the ignore file is actually shipped. - Advise users to inspect `git status` and staged changes before committing. - If credentials have already been committed, revoke and rotate them immediately, then purge them from repository history using an appropriate history-rewriting tool. - Enable repository secret scanning as a secondary control. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/imap.js:15
Finding
Remote IMAP Connections Can Transmit Credentials Without Enforced TLS<![CDATA[ ## Vulnerability Details **File Location**: `scripts/imap.js:15-22` **Vulnerability Type**: Insecure transmission of credentials and mailbox data **Risk Level**: High ```javascript const config = { imap: { user: process.env.IMAP_USER, password: process.env.IMAP_PASS, host: process.env.IMAP_HOST || '127.0.0.1', port: parseInt(process.env.IMAP_PORT) || 1143, tls: process.env.IMAP_TLS === 'true', authTimeout: 10000, tlsOptions: { rejectUnauthorized: process.env.IMAP_REJECT_UNAUTHORIZED !== 'false', }, }, }; ``` The documented default configuration in `SKILL.md:41-46` includes: ```bash IMAP_HOST=127.0.0.1 IMAP_PORT=1143 IMAP_USER=your@email.com IMAP_PASS=your_password IMAP_TLS=false IMAP_REJECT_UNAUTHORIZED=false ``` ### Technical Analysis TLS is enabled only when `IMAP_TLS` is exactly the string `true`. The Skill accepts an arbitrary user-configured IMAP host, but it does not reject unencrypted connections when that host is remote. Consequently, a user can configure a non-loopback server while leaving TLS disabled and transmit authentication credentials and mailbox data without an adequately protected transport. Certificate verification can also be disabled through `IMAP_REJECT_UNAUTHORIZED=false`. Although this option may be needed for a trusted local ProtonMail Bridge using a self-signed certificate, applying it to a remote endpoint removes server-identity verification and enables man-in-the-middle interception. Credential transmission to the selected IMAP server is necessary for the declared functionality. Permitting plaintext or unauthenticated transport to arbitrary remote hosts is not necessary and exceeds a safe least-privilege implementation. ### Attack Path 1. The user configures a remote IMAP host but leaves `IMAP_TLS=false`, or disables certificate verification. 2. The Skill connects over an untrusted local network, public Wi-Fi, compromised router, or attacker-controlled DNS path. 3. A network ...[truncated 803 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Reject non-loopback IMAP connections unless encrypted transport is enabled. - Default to TLS on port 993 for remote servers. - If STARTTLS is supported, explicitly configure and verify the protocol upgrade rather than assuming `tls: false` provides encryption. - Keep certificate verification enabled by default. - Restrict any certificate-verification exception to a validated loopback ProtonMail Bridge configuration. - Prefer certificate pinning or installation of the trusted Bridge certificate over globally disabling verification. - Emit a clear error rather than a warning when a remote configuration would send credentials without encryption. - Separate local Bridge presets from generic remote-server presets so insecure local compatibility settings are not reused for Internet endpoints. - Update the documentation to discourage obsolete options such as Gmail's “less secure app access” and recommend app-specific passwords or OAuth-supported alternatives. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (29)

Ae1

High
Category
analysis-evasion
Content
node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/imap.js check [--limit 10] [--mailbox INBOX] [--recent 2h]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Known Vulnerable Dependency: linkify-it==5.0.0 — 2 advisory(ies): CVE-2026-48801 (LinkifyIt#match scan loop has quadratic algorithmic complexity); CVE-2026-59887 (linkify-it: Quadratic-complexity DoS via the `mailto:` validator scan-loop on at)

High
Category
Supply Chain
Confidence
95% confidence
Finding
The lockfile includes linkify-it 5.0.0, which is reported vulnerable to quadratic-time parsing behavior. In this skill, that package is pulled in via mailparser for processing email bodies, so a crafted email containing pathological link patterns could cause excessive CPU consumption and degrade availability. This is primarily a denial-of-service risk rather than direct code execution.

Known Vulnerable Dependency: nodemailer==7.0.11 — 10 advisory(ies): CVE-2026-82661 (Nodemailer: CRLF injection in Nodemailer List-* header comments allows arbitrary); GHSA-2x7j-588g-ccc2 (Nodemailer: Quadratic (O(n²)) time complexity in addressparser allows remote den); GHSA-8m3c-c648-2xjj (Nodemailer: resolveContent() on a MailMessage bypasses disableFileAccess/disable) +7 more

High
Category
Supply Chain
Confidence
83% confidence
Finding
The lockfile includes nodemailer 7.0.11 with multiple advisories, including CRLF injection and content resolution issues. Although this skill is described as IMAP-focused rather than sending mail, mailparser depends on nodemailer internals, and vulnerable code may still be reachable depending on how message data is processed. The main likely impacts are denial of service or unsafe handling of crafted message content rather than guaranteed exploitation from this file alone.

Known Vulnerable Dependency: semver==5.3.0 — 1 advisory(ies): CVE-2022-25883 (semver vulnerable to Regular Expression Denial of Service)

High
Category
Supply Chain
Confidence
80% confidence
Finding
The lockfile includes semver 5.3.0, which is vulnerable to ReDoS. Here it is only a transitive dependency of utf7 used by imap, and package-lock evidence alone does not show attacker-controlled semver strings are parsed during normal email operations. This is a real vulnerable component, but in this skill context its exploitability appears limited.

Credential Access

High
Category
Privilege Escalation
Content
const imaps = require('imap-simple');
const { simpleParser } = require('mailparser');
require('dotenv').config({ path: __dirname + '/../.env' });

// Configuration from environment
const config = {
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
read -s -p "IMAP Password (from Bridge): " PASSWORD
echo ""

# Create .env file
cat > .env << EOF
# IMAP Email Configuration
# Generated: $(date)
Confidence
92% confidence
Finding
This finding corresponds to the code path that captures a sensitive IMAP password and immediately proceeds to persist it in a .env file. While prompting for a password is normal setup behavior, coupling it with plaintext local storage creates credential exposure risk if the file is read by other processes or accidentally shared.

Credential Access

High
Category
Privilege Escalation
Content
echo ""

# Create .env file
cat > .env << EOF
# IMAP Email Configuration
# Generated: $(date)
Confidence
97% confidence
Finding
The here-document creates a .env file containing IMAP_USER and IMAP_PASS values, which stores mailbox credentials in plaintext. In the context of an email-management skill, exposed credentials can enable unauthorized reading and modification of email, making this more sensitive than a generic low-value secret.

Credential Access

High
Category
Privilege Escalation
Content
EOF

echo ""
echo "✅ Created .env file"
echo ""
echo "Testing connection..."
echo ""
Confidence
85% confidence
Finding
The line itself is only a status message, but in context it confirms successful creation of the plaintext .env file that holds the IMAP credentials. The security issue is not the echo statement alone; it is part of the same credential-storage flow and reinforces that sensitive data has been persisted locally.

Credential Access

High
Category
Privilege Escalation
Content
"notes": [
        "Dependencies are managed via package.json",
        "Run 'npm install' in the skill directory to install required packages",
        "Create .env file with IMAP credentials before use"
      ]
    }
  },
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"notes": [
        "Dependencies are managed via package.json",
        "Run 'npm install' in the skill directory to install required packages",
        "Create .env file with IMAP credentials before use"
      ]
    }
  },
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"notes": [
        "Dependencies are managed via package.json",
        "Run 'npm install' in the skill directory to install required packages",
        "Create .env file with IMAP credentials before use"
      ]
    }
  },
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"notes": [
        "Dependencies are managed via package.json",
        "Run 'npm install' in the skill directory to install required packages",
        "Create .env file with IMAP credentials before use"
      ]
    }
  },
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill exposes access to environment-stored IMAP credentials and email operations but does not declare an explicit tool scope such as allowed tools or permissions. In an agent environment, this can lead to overbroad execution and unclear trust boundaries, increasing the chance that the skill is invoked with unintended access to secrets or shell capabilities.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation recommends setting IMAP_REJECT_UNAUTHORIZED=false for self-signed certificates without clearly warning that this disables certificate validation and enables man-in-the-middle interception. Even if intended for ProtonMail Bridge on localhost, copying this guidance to other IMAP deployments could expose credentials and email content to network attackers.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This skill handles highly sensitive email contents and explicitly documents cron delivery to external channels like iMessage, but it does not warn users that fetched or summarized messages may contain personal, financial, legal, or authentication data. Without a clear disclosure, users may unknowingly forward sensitive mailbox contents outside the email system, causing privacy breaches or data leakage.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script reads IMAP credentials directly from environment variables, which is sensitive credential access in a code file. While the file has general comments about being an IMAP CLI, there is no confirmation prompt, user-facing disclosure, or explicit warning near the credential handling explaining that mailbox credentials will be consumed.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The markAsRead and markAsUnread functions modify message flags, which changes mailbox state, but they perform the action without any confirmation prompt or prior warning comment/documentation about altering message status. Although the command names imply the behavior, the file does not provide an explicit safety disclosure for these state-changing operations.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The script collects an IMAP password and writes it directly into a local .env file in plaintext. This is dangerous because any local user, backup system, shell history exposure, accidental repository commit, or later file disclosure could expose credentials that grant access to the user's mailbox.

Known Vulnerable Dependency: mailparser==3.9.1 — 1 advisory(ies): CVE-2026-3455 (mailparser vulnerable to Cross-site Scripting)

Low
Category
Supply Chain
Confidence
86% confidence
Finding
The lockfile includes mailparser 3.9.1, which has an XSS advisory. In an IMAP email skill, parsing attacker-controlled email HTML is core functionality, so if parsed output is later rendered in a UI or webview without sanitization, malicious email content could execute script in the consuming context. The package-lock alone does not prove exploitability, but the dependency is real and the skill context makes it relevant.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"search": "node scripts/imap.js search"
  },
  "dependencies": {
    "imap-simple": "^5.1.0",
    "mailparser": "^3.7.1",
    "dotenv": "^16.4.7"
  },
Confidence
95% confidence
Finding
The dependency is specified with a caret range (^5.1.0), which allows automatic installation of newer minor/patch releases rather than a single immutable version. This increases supply-chain risk and can introduce unexpected behavior or newly disclosed vulnerabilities during future installs, though by itself it is not an immediately exploitable flaw in this file.

Static analysis

No suspicious patterns detected.