Back to skill

Security audit

Email Sender (繁體中文版)

Security checks for vulnerabilities and agentic risk

Overview

This email skill mostly matches its stated purpose, but its template manager can escape the template folder and modify or delete local .html/.txt files, and it ships with a live-looking SMTP profile that should not be bundled.

Review before installing. Configure your own SMTP profile and remove the bundled sample profile, use app-specific passwords, avoid sending passwords in email templates, and do not let untrusted input control template names or HTML template variables. Treat attachments as sensitive because the skill can send any readable file path you provide.

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/template_manager.py:45
Finding

Template Name Path Traversal Enables Filesystem Access Outside the Template Directory

Content
View full analysis
\n\n{body}" else: full_content = f"# SUBJECT: {subject}\n\n{body}" # Save template try: with open(template_path, 'w', encoding='utf-8') as f: f.write(full_content) ``` ```python # scripts/template_manager.py:162-179 html_path = os.path.join(TEMPLATES_DIR, f"{template_name}.html") txt_path = os.path.join(TEMPLATES_DIR, f"{template_name}.txt") template_path = None if os.path.exists(html_path): template_path = html_path elif os.path.exists(txt_path): template_path = txt_path else: print(f"⚠️ Template '{template_name}' does not exist.") return False # Delete file try: os.remove(template_path) ``` ### Technical Analysis The `template_name` value is concatenated into filesystem paths without validating its character s ...[truncated 2102 chars]
Remediation
View remediation
str: if not SAFE_TEMPLATE_NAME.fullmatch(name): raise ValueError("Invalid template name") return name ``` 2. Resolve every candidate path and verify directory containment: ```python from pathlib import Path TEMPLATE_ROOT = Path(TEMPLATES_DIR).resolve() def safe_template_path(name: str, extension: str) -> Path: validate_template_name(name) candidate = (TEMPLATE_ROOT / f"{name}{extension}").resolve() if candidate.parent != TEMPLATE_ROOT: raise ValueError("Template path escapes the template directory") return candidate ``` 3. Reject absolute paths, path separators, `..`, null bytes, and unexpected extensions. 4. Apply the same safe path-construction function consistently to load, create, overwrite, and delete operations. 5. For writes, consider atomic creation with exclusive mode when overwrite is not explicitly authorized. 6. Add tests covering `../`, absolute paths, nested traversal, symbolic links, and platform-specific separators. 7. If untrusted local users can modify the template directory, address symbolic-link traversal by opening files through a trusted directory descriptor and disabling symlink following where supported. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/template_manager.py:82
Finding

Unescaped Template Variables Permit Arbitrary HTML Injection into Email Bodies

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/templates/welcome.html:10
Finding

Bundled Welcome Template Encourages Plaintext Password Transmission by Email

Content
View full analysis
  • 用戶名:{{username}}
  • 初始密碼:{{password}}
``` The same insecure template is embedded in the default-template generator: ```python # scripts/template_manager.py:350-354
  • 用戶名:{{username}}
  • 初始密碼:{{password}}
``` ### Technical Analysis The bundled welcome template explicitly accepts a password variable and includes the resulting plaintext credential in an email body. Email is not an appropriate channel for distributing reusable passwords because messages commonly remain in sender and recipient mailboxes, backups, archives, notification previews, forwarding chains, and administrative mail logs. Although SMTP transport may be encrypted, transport encryption does not protect the credential after delivery and does not guarantee end-to-end confidentiality. The duplicate definition in `DEFAULT_TEMPLATES` recreates the insecure template whenever default templates are initialized. ### Attack Path 1. An operator creates a user account with an initial password. 2. The operator invokes the welcome template and passes the credential through the `password` variable. 3. Template substitution inserts the plaintext password into the HTML body. 4. The Skill sends the email through the configured SMTP service. 5. Copies of the credential may persist in sent mail, recipient mail, server-side archives, backups, logs, or forwarded messages. 6. Anyone who later gains access to one of those copies can attempt to authenticate as the recipient, particularly if the initial password has not yet been changed or was reused elsewhere. ### Impact Assessment Exposure can lead to compromise of accounts initialized with ...[truncated 320 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (47)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill claims support for template management and attachments, but the supplied description also suggests undeclared access to smtp_config.json and macOS Keychain via system utilities. In security-sensitive tooling, incomplete or inaccurate capability disclosure is dangerous because it obscures credential access and makes it harder to assess whether the skill should be trusted with local secrets.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill claims support for template management and attachments, but the supplied description also suggests undeclared access to smtp_config.json and macOS Keychain via system utilities. In security-sensitive tooling, incomplete or inaccurate capability disclosure is dangerous because it obscures credential access and makes it harder to assess whether the skill should be trusted with local secrets.

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 · README.md (reported line 228)May include surrounding context.

md
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
#!/usr/bin/env python3
"""
SMTP 配置管理腳本
使用 macOS Keychain 安全存儲密碼
"""

import json

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

python
# 配置文件路徑
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(CONFIG_DIR, "smtp_config.json")
KEYCHAIN_SERVICE = "openclaw-email-sender"


def run_command(cmd):

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

python
# 配置文件路徑
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(CONFIG_DIR, "smtp_config.json")
KEYCHAIN_SERVICE = "openclaw-email-sender"


def run_command(cmd):

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

python
# 配置文件路徑
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(CONFIG_DIR, "smtp_config.json")
KEYCHAIN_SERVICE = "openclaw-email-sender"


def run_command(cmd):

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

python
# 配置文件路徑
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(CONFIG_DIR, "smtp_config.json")
KEYCHAIN_SERVICE = "openclaw-email-sender"


def run_command(cmd):

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

python
# 配置文件路徑
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(CONFIG_DIR, "smtp_config.json")
KEYCHAIN_SERVICE = "openclaw-email-sender"


def run_command(cmd):

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

python
# 配置文件路徑
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(CONFIG_DIR, "smtp_config.json")
KEYCHAIN_SERVICE = "openclaw-email-sender"


def run_command(cmd):

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

python
return None, e.stderr.strip()


def keychain_add_password(account, password):
    """將密碼添加到 macOS Keychain"""
    cmd = [
        "security", "add-generic-password",

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

python
return None, e.stderr.strip()


def keychain_add_password(account, password):
    """將密碼添加到 macOS Keychain"""
    cmd = [
        "security", "add-generic-password",

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

python
return None, e.stderr.strip()


def keychain_add_password(account, password):
    """將密碼添加到 macOS Keychain"""
    cmd = [
        "security", "add-generic-password",

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

python
return None, e.stderr.strip()


def keychain_add_password(account, password):
    """將密碼添加到 macOS Keychain"""
    cmd = [
        "security", "add-generic-password",

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

python
return None, e.stderr.strip()


def keychain_add_password(account, password):
    """將密碼添加到 macOS Keychain"""
    cmd = [
        "security", "add-generic-password",

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

python
return None, e.stderr.strip()


def keychain_add_password(account, password):
    """將密碼添加到 macOS Keychain"""
    cmd = [
        "security", "add-generic-password",

Static analysis

No suspicious patterns detected.