Back to skill

Security audit

Email Bridge

Security checks for vulnerabilities and agentic risk

Overview

This email skill is mostly coherent, but it needs Review because it handles mailbox credentials, caches full email content, and automatically sends email-derived data including verification codes into the assistant with weak containment.

Review this skill carefully before installing. It can read and cache mailbox contents, store reusable mail credentials locally, send email through configured accounts, and push new-email notifications to OpenClaw. Protect ~/.email-bridge, avoid putting passwords or authorization codes in command-line --config arguments, consider disabling include_verification_codes or OpenClaw notifications, and revoke/rotate mail tokens if you stop using it.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
email_bridge/daemon.py:507
Finding

Untrusted Email Headers Are Forwarded into the Agent Session Without Effective Prompt-Injection Isolation

Content
View full analysis
str: if not sender: return "Unknown" result = re.sub(r'[<>"\']', '', sender) result = remove_invisible_chars(result) if len(result) > max_length: result = result[:max_length] + "..." return result.strip() def sanitize_subject(subject: str, max_length: int = 100) -> str: if not subject: return "(No subject)" result = remove_invisible_chars(subject) result = result.replace('\n', ' ').replace('\r', ' ') if len(result) > max_length: result = result[:max_length].rsplit(' ', 1)[0] + "..." return result.strip() ``` ### Technical Analysis Email sender names and subject lines are fully attacker-controlled. The daemon includes these values in a free-form text notification and submits the notification to OpenClaw using `openclaw system event`. Although the project contains a blacklist-based `sanitize_for_notification()` function, it is not applied to sender names or subject lines. `sanitize_sender()` only removes a small set of punctuation, while `sanitize_subject()` only removes invisible characters and line breaks. Neit ...[truncated 2000 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
email_bridge/db.py:19
Finding

Authorization Codes, OAuth Tokens, and Full Email Content Are Stored Without Enforced Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
email_bridge/cli.py:50
Finding

Documented Credential Setup Exposes Secrets Through Command-Line Arguments and Shell History

Content
View full analysis
--config '{"password": "YOUR_APP_PASSWORD"}' ``` ### Technical Analysis Command-line arguments are not an appropriate channel for reusable credentials. Depending on the operating system and environment, arguments can be exposed through: - Shell history. - Process-listing tools. - Process ...[truncated 1647 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
pyproject.toml:24
Finding

First-Run Installation Resolves Mutable and Unpinned Third-Party Dependencies

Content
View full analysis
=8.0", "pydantic>=2.0", "google-api-python-client>=2.0", "google-auth>=2.0", "google-auth-oauthlib>=1.0", "imaplib2>=3.6", ] ``` The launcher automatically invokes pip when it cannot find the command: ```python def install_package(): """Install email-bridge package.""" if sys.version_info < (3, 10): sys.exit(1) subprocess.run( [sys.executable, "-m", "pip", "install", "-e", str(SKILL_DIR)], check=True ) def main(): if not is_installed(): install_package() cmd = [EMAIL_BRIDGE_CMD] + sys.argv[1:] result = subprocess.run(cmd) sys.exit(result.returncode) ``` The installation script also resolves dependencies without a locked, hash-verified set: ```bash if command -v uv &> /dev/null; then uv sync source .venv/bin/activate elif command -v pip &> /dev/null; then python3 -m venv .venv source .venv/bin/activate pip install -e . fi ``` ### Technical Analysis The reviewed dependencies use legitimate-looking PyPI package names and no unsafe custom package index was found. However, the absence of exact version pins, a verified lock file, and package hashes means installation results can change after the Skill has been reviewed. The first-run wrapper increases this exposure by automatically launching pip when `email-bridge` is unavailable. Dependency installation can execute package build backends and installation-time code. A future compromised release, account takeover, or incompatible dependency update could therefore affect users without any change to the reviewed Skill source. The subprocess calls themselves use argument arrays ...[truncated 1191 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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 (89)

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documented data flow explicitly extracts verification codes and then pushes notifications to the AI assistant, semantically routing sensitive authentication data to another system. In the context of an email-bridge skill, this is especially dangerous because email is commonly used for MFA, password resets, and account recovery, so disclosure can directly facilitate unauthorized access.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The supplied code chunk is narrowly focused on Gmail read-only access and message retrieval/parsing. It handles OAuth credentials, token caching, Gmail API calls, and extraction of plain text/HTML bodies from Gmail messages. It does not implement the prominently declared features of real-time notifications, category classification, verification code extraction, or HTML sanitization. It also only supports Gmail in this chunk, whereas the declared description claims support for Gmail, QQ Mail, and NetEase. While this may be one adapter file within a larger system, based on the provided code alone the behavior is materially narrower than the declared purpose, so this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description promises several user-facing capabilities: real-time notifications, 7-category smart categorization, verification code extraction, HTML sanitization, and support for Gmail/QQ/NetEase. The supplied code only provides low-level IMAP connectivity and message retrieval/parsing for QQ and NetEase providers. It reads inbox messages and extracts headers/body content, but there is no code for notification delivery, classification, code extraction, or sanitizing HTML. Additionally, Gmail support is not implemented in this chunk. This is a material description-to-behavior mismatch rather than a mere partial implementation detail, because the advertised primary features are absent from the code shown.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The supplied code chunk does not implement the user-facing email management features described. Instead, it provides a mock adapter for demo/testing that loads sample emails from a local fixtures file and exposes basic fetch/get operations. This is materially different from the declared functionality of real provider support, notifications, categorization, code extraction, and sanitization. While this could be a supporting internal component of a larger email skill, taken on its own the behavior is substantially narrower and different than the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description emphasizes email management features focused on incoming-message handling and processing: notifications, categorization, code extraction, and HTML sanitization. The supplied code instead provides outbound SMTP functionality for sending emails and testing SMTP authentication. Sending email is a distinct capability not mentioned in the description, making this a material mismatch. While provider support overlaps (Gmail, QQ Mail, NetEase), the primary behavior of this code chunk is different from the declared purpose, and none of the highlighted management/analysis features appear here.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code largely fits an email bridge/management tool: account management, message listing/searching, syncing, verification-code extraction, and daemon-based monitoring/notifications are all consistent with the description. Provider support for Gmail, QQ, and NetEase is also reflected. However, there are material discrepancies. First, the code includes a send command that sends outbound email, which is a notable undeclared capability. Second, the extraction feature also pulls action links, not just verification codes, which is another undeclared capability. On the other side, the description specifically claims smart categorization with 7 categories and HTML sanitization, but this CLI chunk does not demonstrate either; only some category display values are referenced, and no sanitization behavior is visible here. Because there is at least one significant undeclared capability (email sending), this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The supplied code chunk is a database access layer, not the higher-level email management functionality described. It stores accounts and messages and supports retrieval/search operations, which are consistent as supporting infrastructure for an email skill. However, the declared description emphasizes substantive end-user features—real-time notifications, smart categorization, verification code extraction, and HTML sanitization—that are not implemented in this code. While a category field exists, the code only stores and filters categories; it does not perform categorization. Likewise, provider support is only represented as a stored enum/value, not actual Gmail/QQ/NetEase integration. Therefore, the description does not accurately represent what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied code chunk is narrowly focused on parsing email text/HTML to extract OTP-style verification codes and classify action links such as verify, reset, unsubscribe, or generic actions. That partially matches the declared verification code extraction feature, but several prominent declared capabilities are absent: no notification logic, no email categorization, no HTML sanitization, and no provider-specific integration for Gmail/QQ Mail/NetEase. This is a description-behavior mismatch because the declared description presents a broader email management skill than what this code chunk actually implements.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description promises a functional email management skill with several active capabilities: notifications, categorization, verification-code extraction, and HTML sanitization. The supplied code chunk does not implement those behaviors; it only defines Pydantic models and enums for accounts and messages. While the providers Gmail, QQ, and NetEase are represented, the code also includes an undeclared MOCK provider. The categorization claim is also inconsistent: the description says 7 categories, while the code defines 5 categories (verification, security, subscription, spam_like, normal). Because the actual code is materially narrower than the declared purpose and lacks the advertised features, this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code generally fits an email-management purpose and does support Gmail, QQ Mail, and NetEase, plus message categorization. However, the declared description emphasizes real-time notifications, verification code extraction, and HTML sanitization, none of which are implemented in this code chunk. Conversely, the code includes materially undeclared functionality: sending emails through SMTP and full account management operations. Because the implemented capabilities differ in important ways from the declared feature set, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description promises concrete email-processing capabilities such as notifications, categorization, code extraction, sanitization, and provider support. The supplied code chunk does not implement any of those behaviors directly. Instead, its primary purpose is installation and invocation of an external package (email-bridge). This is a materially different behavior from the declared functional description for the supplied code chunk. While bootstrap installation can be a supporting detail, here the entire visible code is devoted to installation/dispatch and exposes an undeclared capability to install software. Therefore this chunk does not accurately represent the declared skill behavior on its own.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The declared description presents a broader multi-provider email management capability with several higher-level features. The actual supplied code chunk is narrowly scoped to unit tests for a Gmail adapter. It demonstrates Gmail-only behavior such as credentials path resolution, token filename sanitization, parsing Gmail message payloads, and adapter-specific error handling. There is no sign in this chunk of the advertised categorization, verification-code extraction, HTML sanitization, real-time notifications, or QQ/NetEase integrations. While a partial code chunk may not expose the full system, based on the supplied code alone the description materially overstates and misrepresents the implemented behavior.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The documentation explicitly states that OAuth credentials and tokens are stored locally and unencrypted, which creates a real credential theft risk if the host account, backups, logs, or filesystem permissions are weak. Email account tokens often provide durable access to sensitive communications and can enable further account compromise or data exfiltration.

Content

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

├── daemon.pid # Daemon process ID ├── daemon.log # Logs └── gmail/ ├── credentials.json # OAuth credentials └── token_*.json # OAuth tokens

text

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Even though the deletion target is limited to ~/.email-bridge, publishing raw recursive deletion commands in a skill can still be abused through copy-paste mistakes, variable expansion issues, or agent mis-execution in shell-enabled environments. Because this skill handles credentials and tokens, cleanup commands deserve stronger guardrails than a bare rm -rf example.

Content

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

md
email-bridge daemon stop

# Remove all stored data
rm -rf ~/.email-bridge

# For Gmail: revoke at https://myaccount.google.com/permissions
# For QQ/NetEase: regenerate authorization codes in email settings

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Even though the deletion target is limited to ~/.email-bridge, publishing raw recursive deletion commands in a skill can still be abused through copy-paste mistakes, variable expansion issues, or agent mis-execution in shell-enabled environments. Because this skill handles credentials and tokens, cleanup commands deserve stronger guardrails than a bare rm -rf example.

Content

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

md
email-bridge daemon stop

# Remove all stored data
rm -rf ~/.email-bridge

# For Gmail: revoke at https://myaccount.google.com/permissions
# For QQ/NetEase: regenerate authorization codes in email settings

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

md
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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

md
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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

md
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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

md
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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 · email_bridge/adapters/gmail.py (reported line 38)May include surrounding context.

python
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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

python
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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 · email_bridge/adapters/gmail.py (reported line 72)May include surrounding context.

python
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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 · email_bridge/adapters/gmail.py (reported line 86)May include surrounding context.

python
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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 · email_bridge/adapters/gmail.py (reported line 125)May include surrounding context.

python
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

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/gmail-setup.md (reported line 82)May include surrounding context.

md
"""Gmail adapter using Gmail API.

    Configuration (via account.config):
        credentials_path: Path to credentials.json from Google Cloud Console
        token_path: Path to store/load OAuth token (default: ~/.email-bridge/gmail/token.json)
        sync_days: Number of days back to sync (default: 7)
        sync_max_messages: Maximum messages per sync (default: 100)

Static analysis

No suspicious patterns detected.