Back to skill

Security audit

Email 163 Com

Security checks for vulnerabilities and agentic risk

Overview

This email-management skill fits its stated purpose, but it needs Review because it handles mailbox credentials and destructive mail actions with weak safeguards and has unsafe attachment download behavior.

Install only if you are comfortable giving this tool access to read, send, move, mark, delete, and download content from your 163.com mailbox. Verify the config uses the official 163.com IMAP/SMTP hosts, protect or rotate the authorization code, avoid bulk delete/move commands unless you have reviewed the target folder and IDs, and be cautious downloading attachments until filename containment is fixed.

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
main.py:146
Finding
Mailbox Credentials Can Be Transmitted to Configuration-Controlled Servers<![CDATA[ ## Vulnerability Details **File Location**: `main.py:146-154` **Additional Locations**: `main.py:235-238`, `main.py:333-357`, `main.py:469-481`, `main.py:497-498`, `main.py:566-567`, `main.py:641-642`, `main.py:719-720` **Vulnerability Type**: Unrestricted credential destination **Risk Level**: High ### Vulnerable Code ```python print(f"\n📧 测试 IMAP 连接...") print(f" 服务器:{config['imap_server']}:{config['imap_port']}") # 创建 SSL 连接 mail = imaplib.IMAP4_SSL(config['imap_server'], config['imap_port']) # 登录 print(f" 登录:{config['email']}") mail.login(config['email'], config['password']) ``` The SMTP path similarly trusts the configured server and resolves it to an IP address: ```python import socket smtp_host = config['smtp_server'] smtp_port = config['smtp_port'] # 解析 IPv4 地址 addr_info = socket.getaddrinfo( smtp_host, smtp_port, socket.AF_INET, socket.SOCK_STREAM ) ipv4_addr = addr_info[0][4][0] print(f" 使用 IPv4 地址:{ipv4_addr}") # 创建 SMTP 连接(强制 IPv4) server = smtplib.SMTP_SSL(ipv4_addr, smtp_port, timeout=30) server.ehlo() server.login(config['email'], config['password']) server.sendmail(config['email'], [args.to], msg.as_string()) server.quit() ``` ### Technical Analysis The Skill necessarily sends a mailbox address and authorization code to IMAP and SMTP servers because authentication is intrinsic to its declared email-management functionality. However, the destination host and port are taken directly from the editable configuration file without an allowlist or destination validation. This conflicts with the package metadata and security documentation, which state that the Skill connects only to `imap.163.com:993` and `smtp.163.com:465`. The implementation permits arbitrary hosts and ports. The SMTP implementation also resolves the configured hostname and constructs the TLS connection using the resulting IP address rather than the intended hostname. This prevents the TLS layer from naturally associating the connection with the confi ...[truncated 1604 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enforce exact destination allowlists before any connection: - IMAP: `imap.163.com` on port `993`. - SMTP: `smtp.163.com` on port `465`. 2. Reject IP literals, alternate ports, Unicode hostname ambiguities, and unexpected server names for this 163.com-specific Skill. 3. Connect to SMTP using the hostname rather than its resolved IP: ```python context = ssl.create_default_context() server = smtplib.SMTP_SSL( "smtp.163.com", 465, timeout=30, context=context ) ``` 4. Create and pass an explicit verified TLS context to both SMTP and IMAP connections. 5. If custom mail servers are intentionally supported, document that broader functionality and require explicit informed opt-in rather than silently trusting configuration values. 6. Validate the configuration before loading credentials into a connection and terminate with a clear error if the destination is not approved. 7. Add automated tests proving that unauthorized hosts, ports, and IP-address destinations are rejected. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
main.py:535
Finding
Untrusted Attachment Filenames Permit Arbitrary File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `main.py:535-542` **Vulnerability Type**: Path traversal through an email attachment filename **Risk Level**: High ### Vulnerable Code ```python filename = part.get_filename() if filename: filename = decode_mime_words(filename) filepath = os.path.join(download_dir, filename) with open(filepath, 'wb') as f: f.write(part.get_payload(decode=True)) file_size = os.path.getsize(filepath) / 1024 print(f"✅ 已下载:{filename} ({file_size:.1f} KB)") attachments.append(filepath) ``` ### Technical Analysis The attachment filename originates from an untrusted MIME header controlled by the email sender. After decoding, it is appended directly to the selected download directory. `os.path.join()` does not enforce containment. A filename containing parent-directory components such as `../../target` can escape the download directory. An absolute filename can cause the download directory to be discarded altogether. The use of `open(filepath, 'wb')` truncates an existing target file without warning. No checks reject absolute paths, directory separators, `.` or `..` components. The implementation also does not resolve the final path and verify that it remains beneath the intended output directory. ### Attack Path 1. An attacker sends the victim an email containing an attachment with a crafted MIME filename, such as `../../.config/application/config.json`. 2. The email is delivered to the victim's mailbox. 3. The victim invokes: ```bash email-163-com attachments --id <message-id> ``` 4. The Skill decodes the attacker-controlled filename. 5. `os.path.join(download_dir, filename)` produces a path outside the intended download directory. 6. The Skill opens that path in `wb` mode and overwrites any existing file writable by the current user. 7. If the selected target is later interpreted as code or configuration, the overwrite may lead to further compromise. ### Impact Assessment The di ...[truncated 616 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat MIME filenames as display metadata, not trusted paths. 2. Reject absolute paths and filenames containing path separators or traversal components. 3. Reduce the supplied name to a safe basename and replace unsafe characters: ```python raw_name = decode_mime_words(part.get_filename()) safe_name = os.path.basename(raw_name.replace("\\", "/")) if not safe_name or safe_name in {".", ".."}: raise ValueError("Unsafe attachment filename") ``` 4. Resolve both the output directory and final path, then enforce containment: ```python base = os.path.realpath(download_dir) destination = os.path.realpath(os.path.join(base, safe_name)) if os.path.commonpath([base, destination]) != base: raise ValueError("Attachment path escapes output directory") ``` 5. Avoid silently replacing existing files. Use exclusive creation mode (`xb`) or generate a collision-safe filename. 6. Consider imposing attachment size limits to prevent disk exhaustion. 7. Add tests for `../`, nested traversal, absolute Unix paths, Windows drive paths, backslash traversal, encoded separators, empty names, and filename collisions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:119
Finding
Mailbox Authorization Code Is Entered with Terminal Echo Enabled<![CDATA[ ## Vulnerability Details **File Location**: `main.py:119-122` **Vulnerability Type**: Visible sensitive credential input **Risk Level**: Medium ### Vulnerable Code ```python print("\n请输入 163 邮箱授权码(不是登录密码!)") print("获取方式:https://mail.163.com -> 设置 -> POP3/SMTP/IMAP") password_input = input("授权码: ").strip() if password_input: config['password'] = password_input ``` ### Technical Analysis Python's standard `input()` function leaves terminal echo enabled. The authorization code is consequently displayed in plaintext while the user types it. The configuration is later protected with mode `0600`, but that protection does not address exposure during entry. The credential may appear in screen sharing, terminal recording, remote support sessions, surveillance footage, or to nearby observers. ### Attack Path 1. The user runs `email-163-com init`. 2. The configuration wizard requests the mailbox authorization code. 3. The user types the code while terminal echo is enabled. 4. The plaintext code is visible on screen. 5. A nearby observer or screen/session recorder captures it. 6. The captured authorization code is used to authenticate to the user's mailbox. ### Impact Assessment An exposed authorization code can grant the observer the same mailbox access available to this client. Depending on server-side permissions, this can include reading messages, sending mail as the user, downloading attachments, changing flags, moving messages, and deleting messages. The issue does not directly elevate operating-system privileges. Its impact is unauthorized access to the user's email account and the sensitive information stored in that account. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `input()` with `getpass.getpass()`: ```python from getpass import getpass password_input = getpass("Authorization code: ").strip() ``` 2. Never print, log, or include the authorization code in exception messages. 3. Clear unnecessary references to the plaintext value after saving or authentication where practical. 4. Prefer an operating-system credential store or keyring over long-term plaintext JSON storage. 5. If file-based storage remains necessary, retain mode `0600`, verify ownership, and reject configurations with permissive file modes. 6. Add a test confirming that initialization uses non-echoing credential input. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (20)

Missing User Warnings

High
Confidence
97% confidence
Finding
The config example instructs users to place an email password/auth code in plaintext in a JSON file and does not warn about credential sensitivity, file permissions, or safer storage mechanisms. This creates a straightforward credential-exposure risk: any local user, backup system, logs, or malware that can read the file may obtain reusable mailbox credentials.

Missing User Warnings

High
Confidence
96% confidence
Finding
The bulk deletion example shows searching a spam folder and then deleting all messages, but it provides no safety warning, preview step, or confirmation mechanism. In an automated or agent-driven setting, this pattern could easily be generalized or misapplied to the wrong folder, causing large-scale unintended mailbox data loss.

Missing User Warnings

High
Confidence
97% confidence
Finding
The tool exposes a destructive batch-delete operation, including an --all mode, without any confirmation prompt, dry-run, safeguard, or secondary approval. In an agent/skill context, this is dangerous because a mistaken invocation, prompt injection, or ambiguous user request could irreversibly delete a user's mailbox contents, especially when combined with --expunge.

File System Enumeration

Medium
Category
Data Exfiltration
Content
**解决**:
```bash
# 检查软链接
ls -la ~/.local/bin/email-163-com

# 重新安装
clawhub uninstall email-163-com
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The installation guide advertises commands for reading, sending, searching, and downloading email attachments without any warning that these operations access sensitive mailbox contents and may modify external state by sending messages. In an agent skill context, omission of privacy and side-effect warnings increases the chance that a user or downstream agent invokes powerful email actions without understanding the data exposure and account-impacting consequences.

Skill Enumeration

Medium
Category
Agent Snooping
Content
## 📚 文档

- **技能说明**: `~/.openclaw/workspace/skills/email-163-com/SKILL.md`
- **使用指南**: `~/.openclaw/workspace/skills/email-163-com/README.md`
- **配置**: `~/.config/email-163-com/config.json`
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly instructs users to store their 163.com email address and authentication secret in a plaintext local JSON config file under the home directory, but it does not warn about file permissions, secret exposure, or safer storage alternatives. For an email-management skill, those credentials grant access to mailbox contents and mail-sending capability, so compromise could expose sensitive communications and enable account abuse.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
| 特性 | 状态 | 说明 |
|------|------|------|
| **配置文件位置** | ✅ `~/.config/email-163-com/config.json` | 用户目录,非系统目录 |
| **文件权限** | ✅ `chmod 600` | 仅所有者可读 |
| **凭证类型** | ✅ 客户端授权码 | 不使用登录密码 |
| **加密存储** | ⚠️ 明文存储 | 建议配合磁盘加密 |
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
| 特性 | 状态 | 说明 |
|------|------|------|
| **配置文件位置** | ✅ `~/.config/email-163-com/config.json` | 用户目录,非系统目录 |
| **文件权限** | ✅ `chmod 600` | 仅所有者可读 |
| **凭证类型** | ✅ 客户端授权码 | 不使用登录密码 |
| **加密存储** | ⚠️ 明文存储 | 建议配合磁盘加密 |
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
| 特性 | 状态 | 说明 |
|------|------|------|
| **配置文件位置** | ✅ `~/.config/email-163-com/config.json` | 用户目录,非系统目录 |
| **文件权限** | ✅ `chmod 600` | 仅所有者可读 |
| **凭证类型** | ✅ 客户端授权码 | 不使用登录密码 |
| **加密存储** | ⚠️ 明文存储 | 建议配合磁盘加密 |
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
email-163-com folders

# 创建文件夹
email-163-com folder create "MyFolder"

# 删除文件夹
email-163-com folder delete "MyFolder"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill documents destructive operations such as deleting emails and folders without clearly warning that these actions may be irreversible or provider-dependent in recoverability. In an agent context, exposing deletion commands without confirmation guidance increases the risk of accidental data loss from user mistakes, prompt misunderstandings, or automation errors.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# 设置配置文件权限(仅自己可读)
chmod 600 ~/.config/email-163-com/config.json
```

### 环境变量(可选)
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This markdown file documents operations such as deleting folders, deleting or moving emails, marking message state, and downloading attachments to disk, but it provides no warning about potential impact on user data or mailbox state. Under the markdown-specific SQP-2 criteria, descriptions of behaviors that can affect user data, privacy, or system integrity should include user-facing warnings.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The module docstring says v1.0.2 adds 'IMAP ID 预发送支持(登录前发送)', implying IMAP ID is transmitted before login to address the Unsafe Login issue. In every implementation path shown, the code calls mail.login(...) first and only then calls mail.xatom('ID', ...), so the documentation directly contradicts the actual behavior.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The batch-move feature can operate on all messages and marks originals as deleted after copying, effectively removing mail from the source folder without any confirmation. In a skill used by an autonomous or semi-autonomous agent, this raises the risk of large-scale unintended mailbox modification or data loss from operator error or adversarial prompting.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The primary user-facing description is written only in Chinese, with no indication that the skill is region-specific or that users can choose another language. This can violate language/locale policy when a skill implicitly forces a language without explicit opt-in or documented justification.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This shell script includes user-facing comments and status/output text in Chinese, including installation guidance and next steps. Per the policy, forcing a specific language or locale without offering user choice or opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
This markdown file uses Chinese throughout, including installation and safety-related instructions, but does not indicate that the skill is China-specific or provide an opt-in language choice. That can violate language/locale policy because users are implicitly forced into a specific language for operational guidance.

Vague Triggers

Low
Confidence
83% confidence
Finding
This manifest file includes a broad capability description for full email management, but it does not specify when the skill should be invoked or what phrases or contexts should activate it. In manifest files, missing trigger specificity can cause unintended invocation overlap with general email-related requests.

Static analysis

No suspicious patterns detected.