Back to skill

Security audit

imap-smtp-email-chinese

Security checks for vulnerabilities and agentic risk

Overview

This email skill largely does what it says, but it needs review because attachment downloads, stored email credentials, and optional TLS verification bypass create meaningful account and local-file risks.

Review this before installing. Use a dedicated app password or limited mailbox account, protect or avoid the .env file, do not disable TLS certificate verification except in a controlled test environment, confirm every outbound email and attachment yourself, and avoid downloading attachments until filenames are sanitized and overwrites are prevented.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/imap.js:329
Finding
Email Attachment Filename Allows Path Traversal and Arbitrary File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/imap.js:329-342` **Vulnerability Type**: Untrusted filename path traversal **Risk Level**: High ### Vulnerable Code ```js for (const attachment of parsed.attachments) { if (specificFilename && attachment.filename !== specificFilename) { continue; } if (attachment.content) { const filePath = path.join(outputDir, attachment.filename); fs.writeFileSync(filePath, attachment.content); downloaded.push({ filename: attachment.filename, path: filePath, size: attachment.size, }); } } ``` ### Technical Analysis The attachment filename originates from an email controlled by its sender. The code appends that untrusted filename directly to the user-selected output directory without sanitizing path separators, removing parent-directory components, or verifying the final resolved path. A filename such as `../../target-file` can cause `path.join()` to construct a path outside `outputDir`. The subsequent `fs.writeFileSync()` call creates or overwrites that destination using the attachment content. No exclusive-create option or overwrite confirmation is used. This violates the expectation that the `download` command only writes files beneath its specified output directory. ### Attack Path 1. An attacker sends an email containing an attachment with a filename containing traversal components, such as `../../home/user/.config/example`. 2. The email reaches the mailbox configured for the Skill. 3. The user or agent invokes: ```bash node scripts/imap.js download <uid> --dir <download-directory> ``` 4. `mailparser` exposes the attacker-provided attachment filename. 5. The Skill joins that filename to `outputDir` without containment validation. 6. `fs.writeFileSync()` writes attacker-controlled attachment data outside the intended directory. 7. If the resolved destination already exists and is writable, it is overwritten. ### Impact Assessment An attacker can ...[truncated 491 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every attachment filename as untrusted. 2. Reduce the supplied name to a safe basename: ```js const safeName = path.basename(attachment.filename || 'attachment.bin'); ``` 3. Reject empty names, `.` and `..`, control characters, path separators, and platform-specific reserved names. 4. Resolve and validate the final destination: ```js const baseDir = path.resolve(outputDir); const destination = path.resolve(baseDir, safeName); if ( destination !== baseDir && !destination.startsWith(baseDir + path.sep) ) { throw new Error('Unsafe attachment filename'); } ``` 5. Avoid silently replacing existing files. Use an exclusive write such as: ```js fs.writeFileSync(destination, attachment.content, { flag: 'wx' }); ``` 6. Consider generating a server-side filename and retaining the original filename only as metadata. 7. Add tests covering `../`, nested traversal, Windows separators, encoded filenames, control characters, and existing destinations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
setup.sh:137
Finding
Setup Stores Reusable Email Credentials in a Plaintext File Without Enforcing Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `setup.sh:137-155` **Vulnerability Type**: Insecure credential storage and file permissions **Risk Level**: Medium ### Vulnerable Code ```bash # Create .env file cat > .env << EOF # IMAP Configuration IMAP_HOST=$IMAP_HOST IMAP_PORT=$IMAP_PORT IMAP_USER=$EMAIL IMAP_PASS=$PASSWORD IMAP_TLS=$IMAP_TLS IMAP_REJECT_UNAUTHORIZED=$REJECT_UNAUTHORIZED IMAP_MAILBOX=INBOX # SMTP Configuration SMTP_HOST=$SMTP_HOST SMTP_PORT=$SMTP_PORT SMTP_SECURE=$SMTP_SECURE SMTP_USER=$EMAIL SMTP_PASS=$PASSWORD SMTP_FROM=$EMAIL SMTP_REJECT_UNAUTHORIZED=$REJECT_UNAUTHORIZED EOF ``` ### Technical Analysis The setup script writes the user's password, application password, or authorization code directly into `.env`. It does not set a restrictive `umask`, explicitly assign mode `0600`, or verify the resulting file permissions. The effective permissions therefore depend on the caller's environment. Under a commonly used `umask` of `022`, a newly created file may be readable by other local users. If `.env` already exists, its previous permissions are retained. The project also contains an `.env` file and no `.gitignore` was present in the audited directory, despite documentation recommending that `.env` be ignored. The bundled values appear to be examples and were not established to be active credentials, but shipping the credential filename encourages accidental inclusion of future real secrets in archives or source-control commits. The same reusable credential is written to both `IMAP_PASS` and `SMTP_PASS`, increasing the consequences of disclosure. ### Attack Path 1. A user runs `setup.sh` and enters an email address and reusable password or authorization code. 2. The script writes the credential to `.env` using the caller's ambient file-creation permissions. 3. The file is created with permissive access, inherited unsafe permissions, included in an archive, or accidentally committed to source control. 4. Another local user or a ...[truncated 825 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set a restrictive file-creation mask before creating the credential file: ```bash umask 077 ``` 2. Create the file securely and enforce owner-only permissions: ```bash install -m 600 /dev/null .env ``` 3. Verify permissions after writing and abort if the file is accessible to group or other users. 4. Ship `.env.example` containing placeholders instead of a populated `.env`. 5. Add `.env` to `.gitignore` and relevant package/archive ignore files. 6. Prefer an operating-system keychain, secret manager, or runtime credential injection instead of persistent plaintext storage. 7. Encourage provider-specific, revocable application passwords with only the necessary mail permissions. 8. Document credential rotation steps for users who accidentally publish `.env`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/smtp.js:29
Finding
Configurable TLS Certificate Verification Bypass Exposes Mail Credentials and Content to Interception<![CDATA[ ## Vulnerability Details **File Location**: `scripts/smtp.js:29-44` **Vulnerability Type**: Improper TLS certificate validation **Risk Level**: High when certificate verification is disabled ### Vulnerable Code ```js function createTransporter() { const config = { host: process.env.SMTP_HOST, port: parseInt(process.env.SMTP_PORT) || 587, secure: process.env.SMTP_SECURE === 'true', // true for 465, false for other ports auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS, }, tls: { rejectUnauthorized: process.env.SMTP_REJECT_UNAUTHORIZED !== 'false', }, }; ``` Equivalent behavior exists for IMAP in `scripts/imap.js:43-64`: ```js function createImapConfig() { return { host: process.env.IMAP_HOST || '127.0.0.1', port: parseInt(process.env.IMAP_PORT) || 993, secure: process.env.IMAP_TLS === 'true', auth: { user: process.env.IMAP_USER, pass: process.env.IMAP_PASS, }, enableUTF8Accept: true, connectionTimeout: 10000, authTimeout: 10000, tls: { rejectUnauthorized: process.env.IMAP_REJECT_UNAUTHORIZED !== 'false', }, id: IMAP_ID, logger: false, }; } ``` ### Technical Analysis Both clients allow certificate authentication to be disabled by setting the corresponding `REJECT_UNAUTHORIZED` variable to `false`. The setup flow explicitly asks whether self-signed certificates should be accepted, while `README.md` and `SKILL.md` recommend disabling verification as a troubleshooting measure. TLS without certificate validation may encrypt traffic but does not establish the identity of the remote server. An active network attacker can present an arbitrary certificate, impersonate the configured IMAP or SMTP endpoint, and terminate the connection without triggering a certificate error. The bypass is conditional and secure validation remains enabled by default. Exploitation therefore requires the user or environment to opt into the ...[truncated 1290 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Keep certificate verification mandatory for normal operation. 2. Replace the Boolean bypass with support for a user-supplied trusted CA certificate: ```js tls: { rejectUnauthorized: true, ca: fs.readFileSync(process.env.SMTP_CA_FILE), } ``` 3. Provide equivalent custom-CA support for IMAP. 4. Remove the recommendation to disable certificate verification from `README.md` and `SKILL.md`. 5. If an emergency override must remain, require an explicit command-line flag, display a prominent warning, and prevent it from becoming a persistent default. 6. Validate that configured hostnames match the intended provider and avoid connecting through insecure redirects or proxies. 7. Recommend certificate renewal or installation of the correct private CA rather than bypassing validation. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description claims a broad IMAP/SMTP email skill with both reading and sending capabilities plus mailbox management actions. This code chunk implements only a narrow subset: checking unread messages in INBOX and listing header metadata for up to five messages. It opens the mailbox in read-only mode, so it cannot mark mail as read/unread, and there is no SMTP logic or attachment handling. While checking unread email is consistent with part of the description, the declared purpose substantially overstates the implemented behavior in this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The code accurately implements most of the declared IMAP-related reading features: checking unread/new mail, fetching message content, searching, listing mailboxes, marking messages read/unread, and handling attachments for downloaded messages. However, it does not contain any SMTP logic or any function to compose/send emails, with or without attachments, which is a material part of the declared purpose. Additionally, the code writes attachments to the local filesystem via a download command, which is not explicitly reflected in the description. The primary mismatch is the missing send-email functionality, so this should be flagged as a description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description presents a combined IMAP/SMTP email skill with both inbox-reading and message-sending capabilities. However, this code chunk is exclusively an SMTP CLI sender using nodemailer. Its commands are limited to 'send' and 'test'; there is no IMAP library usage, mailbox access, message retrieval, unread checking, search, or flag manipulation. The sending capability with attachments is consistent with part of the description, but the broader declared functionality is not represented by the provided code chunk.

Credential Access

High
Category
Privilege Escalation
Content
const Imap = require('imap');
const fs = require('fs');

const env = fs.readFileSync('../.env', 'utf8');
const config = {};
env.split('\n').forEach(line => {
  const [key, ...valueParts] = line.split('=');
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
const Imap = require('imap');
const fs = require('fs');

const env = fs.readFileSync('../.env', 'utf8');
const config = {};
env.split('\n').forEach(line => {
  const [key, ...valueParts] = line.split('=');
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
const Imap = require('imap');
const fs = require('fs');

const env = fs.readFileSync('../.env', 'utf8');
const config = {};
env.split('\n').forEach(line => {
  const [key, ...valueParts] = line.split('=');
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
const Imap = require('imap');
const fs = require('fs');

const env = fs.readFileSync('../.env', 'utf8');
const config = {};
env.split('\n').forEach(line => {
  const [key, ...valueParts] = line.split('=');
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
const Imap = require('imap');
const fs = require('fs');

const env = fs.readFileSync('../.env', 'utf8');
const config = {};
env.split('\n').forEach(line => {
  const [key, ...valueParts] = line.split('=');
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
echo "  IMAP/SMTP Email Skill Setup"
echo "================================"
echo ""
echo "This script will help you create a .env file with your email credentials."
echo ""

# Prompt for email provider
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
echo "  IMAP/SMTP Email Skill Setup"
echo "================================"
echo ""
echo "This script will help you create a .env file with your email credentials."
echo ""

# Prompt for email provider
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

High
Confidence
98% confidence
Finding
The script offers users an easy option to disable certificate verification by setting REJECT_UNAUTHORIZED=false, but does not explain that this defeats TLS server authentication. That enables man-in-the-middle attacks against IMAP/SMTP connections, allowing theft of email credentials and interception or modification of email traffic.

Credential Access

High
Category
Privilege Escalation
Content
fi
fi

# Create .env file
cat > .env << EOF
# IMAP Configuration
IMAP_HOST=$IMAP_HOST
Confidence
92% confidence
Finding
This line begins the heredoc that writes a .env file containing IMAP and SMTP credentials. In the context of an email integration skill, stored credentials can grant full mailbox access and permit sending email as the user, so unauthorized disclosure has significant account and privacy impact.

Credential Access

High
Category
Privilege Escalation
Content
fi

# Create .env file
cat > .env << EOF
# IMAP Configuration
IMAP_HOST=$IMAP_HOST
IMAP_PORT=$IMAP_PORT
Confidence
92% confidence
Finding
This finding points into the credential-writing block where sensitive configuration is persisted to .env. Although the line itself is a config key, it is part of a block that stores secrets and therefore contributes to credential exposure risk if the file is accessed by unauthorized users or accidentally shared.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README instructs users to place live IMAP/SMTP credentials in a local .env file and describes broad email read/send capabilities, but it does not clearly warn about the sensitivity of mailbox contents, outbound email abuse, or the need to protect secrets from logs, source control, and unauthorized access. In an email skill, these omissions materially increase the chance of credential exposure or unsafe deployment because compromise enables both data exfiltration from inboxes and impersonation via SMTP.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents access to environment-stored credentials and arbitrary network communication with IMAP/SMTP servers, but it does not declare any explicit tool scope or permission boundaries. This is dangerous because an agent or user may invoke a capability that can read mailbox contents and send mail without clear least-privilege constraints or consent expectations.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The skill includes an attachment download feature that writes files to the local filesystem but does not prominently warn users about the risks of saving untrusted content locally. This is dangerous because email attachments may contain malware, sensitive data, or unexpected file types, and an agent may download them into unsafe locations without adequate user awareness.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill supports sending email and attachments over SMTP but does not include a prominent warning that this may transmit sensitive information externally and can be abused for unauthorized outbound communication. In agent contexts, this is especially risky because a prompt-influenced action could send data, files, or messages to attacker-controlled recipients.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The slug `imap-smtp-email-chinese` explicitly encodes a language constraint ('chinese') in the skill identity, but this manifest provides no indication that users can choose another language or that the locale restriction is justified. For all file types, natural-language policy concerns include forcing a specific language without user opt-in.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script loads sensitive configuration values from ../.env, including IMAP credentials later used for mailbox access, but provides no comment, docstring, or user-facing disclosure that it accesses stored secrets. This is a code file, so sensitive credential access should have some visible warning or explanation unless clearly disclosed elsewhere in the skill description.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The downloadAttachments flow creates directories and writes attachment contents to local files, which is a safety-relevant file write operation. While the function name implies downloading, this file contains no confirmation prompt and no explicit warning comment/docstring near the write path to disclose that it will modify the local filesystem.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script stores the email username and password/app password in a plaintext .env file, which can be exposed through weak filesystem permissions, accidental commits, backups, shell history-adjacent workflows, or other local compromise. In an email skill, these credentials provide direct access to inbox contents and outbound mail, making plaintext secret storage materially sensitive.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"search": "node scripts/imap.js search"
  },
  "dependencies": {
    "dotenv": "^16.6.1",
    "iconv-lite": "^0.7.2",
    "imap": "^0.8.19",
    "imap-simple": "^5.1.0",
Confidence
95% confidence
Finding
The dependency uses a caret range instead of an exact pinned version, which makes builds non-reproducible and can silently pull in newly published package versions. In a credential-handling email skill, this increases supply-chain risk because compromised or regressed upstream releases could gain access to IMAP/SMTP credentials or message contents.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "dependencies": {
    "dotenv": "^16.6.1",
    "iconv-lite": "^0.7.2",
    "imap": "^0.8.19",
    "imap-simple": "^5.1.0",
    "imapflow": "^1.2.10",
Confidence
95% confidence
Finding
The dependency is specified with a floating caret range, so different installs may resolve to different code over time. That creates a supply-chain exposure window where a malicious or vulnerable upstream release could be introduced without any source change in this repository.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dependencies": {
    "dotenv": "^16.6.1",
    "iconv-lite": "^0.7.2",
    "imap": "^0.8.19",
    "imap-simple": "^5.1.0",
    "imapflow": "^1.2.10",
    "mailparser": "^3.9.3",
Confidence
95% confidence
Finding
Using an unpinned version for an IMAP library is risky because the installed package may change between deployments, affecting code that handles mailbox access and authentication. While not an exploit by itself, it weakens supply-chain integrity and incident reproducibility.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dotenv": "^16.6.1",
    "iconv-lite": "^0.7.2",
    "imap": "^0.8.19",
    "imap-simple": "^5.1.0",
    "imapflow": "^1.2.10",
    "mailparser": "^3.9.3",
    "nodemailer": "^7.0.13"
Confidence
95% confidence
Finding
A non-exact dependency version permits automatic resolution to newer releases, which can introduce vulnerable or malicious code unexpectedly. Because this skill processes email data, any compromised dependency could expose sensitive messages, attachments, or credentials.

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.potential_exfiltration

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/check-inbox.js:17

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/test-conn.js:19

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
scripts/check-inbox.js:4