Back to skill

Security audit

Email Customer Assistant

Security checks for vulnerabilities and agentic risk

Overview

This email assistant mostly matches its stated purpose, but it has under-disclosed handling of mailbox data and a serious credential-boundary issue that users should review before installing.

Review this skill before installing. Use a dedicated 91Skillhub license token only, do not rely on OPENAI_API_KEY for licensing, and rotate any credential that may have been passed to the validation endpoint. Only enable AI and Feishu processing for mailboxes where third-party handling of email content is approved, use narrow Feishu recipients or webhooks, and avoid cron deployment until dry-run and data-sharing controls are fixed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/check_emails.py:127
Finding

AI API Credential Forwarded to an Unrelated License Validation Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check_emails.py:221
Finding

Dry-Run Option Does Not Enforce the Promised No-Push Behavior

Content
View full analysis
Remediation
View remediation
list: ... if ( not dry_run and results and self.config.get("feishu", {}).get("enabled") ): self.pusher.push_summary(results) ``` 2. Invoke it with the parsed option: ```python results = assistant.process_emails( limit=args.limit, dry_run=args.dry_run, ) ``` 3. Apply the same guard to every outbound notification path, including urgent alerts and daily digests. 4. Decide and document whether dry-run should also suppress AI API calls. If so, use local classification and template replies only. 5. Implement or replace the missing `push_summary()` method so the behavior is explicit and testable. 6. Add unit tests that mock network clients and assert that no HTTP request occurs under `--dry-run`. 7. Display a clear summary of which network operations are enabled before processing sensitive mail. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reply_generator.py:118
Finding

Untrusted Email Content Is Embedded Directly into AI Prompts

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unnecessary Standard-Library Name Dependency Creates Package Shadowing Risk

Content
View full analysis
=2.3.0 email>=4.0.0 openai>=1.0.0 pyyaml>=6.0 requests>=2.28.0 ``` ### Technical Analysis Python already provides the `email` package as part of its standard library. Declaring a separate package named `email` is unnecessary and can introduce package shadowing or dependency-confusion risk. A third-party distribution using the same name may replace or interfere with imports expected to resolve to the standard-library implementation. Installation also creates an additional supply-chain trust relationship that is not required by the Skill's functionality. All listed dependencies use open-ended minimum-version constraints. A future release can therefore be installed automatically without review, potentially introducing incompatible or compromised code. ### Attack Path 1. The user follows the documentation and runs `pip install -r requirements.txt`. 2. The package installer resolves the third-party `email` distribution and the latest versions satisfying the open-ended constraints. 3. The unnecessary package may shadow or alter expected standard-library behavior. 4. Package installation hooks or later imports can execute code from the resolved distribution. 5. A compromised, malicious, or incompatible release can affect the environment in which the Skill runs. No evidence establishes that the currently resolved package is malicious. The finding concerns avoidable supply-chain exposure and unsafe dependency specification. ### Impact Assessment The impact depends on the behavior of packages resolved at installation time. A malicious or compromised dependency could potentially: - Execute code with the privileges of the user installing or running the Skill. - Access configuration files containing IMAP, AI, and Feish ...[truncated 289 chars]
Remediation
View remediation
=4.0.0` entry because `email` is supplied by Python's standard library. 2. Pin every required dependency to a reviewed version. 3. Generate and commit a reproducible lock file. 4. Use cryptographic hashes for dependency artifacts where supported. 5. Install dependencies in an isolated virtual environment rather than system-wide. 6. Run dependency vulnerability and provenance checks in continuous integration. 7. Review package names for typosquatting and dependency-confusion risks. 8. Upgrade pinned versions through a controlled review process rather than accepting all future releases automatically. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (32)

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation contains a material contradiction: it claims the skill is 'read-only' and does not send email, while earlier sections explicitly advertise reply generation and sending after user confirmation. This can mislead users and reviewers about the true capability boundary of the skill, causing unsafe deployment decisions or overbroad trust in a component that may perform outbound communications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The listing says the skill fetches mailbox contents, uses external AI APIs for classification/reply generation, and sends alerts to Feishu, but it does not clearly warn users that email content and metadata may be transmitted to third-party services. In a customer-service email workflow, messages can contain sensitive personal, financial, or business information, so lack of explicit disclosure creates a real privacy and data-handling risk even if the feature is intentional.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly describes pulling mailbox contents, classifying them with AI, generating replies, and pushing summaries to Feishu, but it does not clearly warn users that potentially sensitive email content will be transmitted to third-party services. This creates a real privacy and compliance risk because users may deploy the skill without understanding that customer emails could leave their environment and be processed externally.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · README.md (reported line 113)May include surrounding context.

设置定时任务(每小时检查一次)

bash
crontab -e
# 添加以下行:
# 0 * * * * cd /home/gem/workspace/agent/skills/email-customer-assistant/scripts && python check_emails.py >> /var/log/email_assistant.log 2>&1

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · SKILLHUB.md (reported line 130)May include surrounding context.

设置定时任务(每小时检查一次)

bash
crontab -e
# 添加以下行:
# 0 * * * * cd /home/gem/workspace/agent/skills/email-customer-assistant/scripts && python check_emails.py >> /var/log/email_assistant.log 2>&1

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This email-processing script performs unrelated token verification against an external service and falls back to reading OPENAI_API_KEY from the environment, causing a sensitive credential to be transmitted to a third party outside the apparent email-assistant workflow. That creates a covert data-exfiltration path for environment secrets and violates least surprise, especially because the key may belong to another service entirely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

Unread emails are fetched and then passed into classification, reply generation, and optional Feishu summary push without any consent gate or warning in this file. In the context of a mail assistant, this means potentially sensitive message content, sender data, and snippets may be disclosed to external AI or messaging services unexpectedly.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI advertises a '--dry-run' mode as 'check only', but this flag is never used to suppress side effects. As written, processing still reaches Feishu push logic, so users may unintentionally send email-derived summaries to an external system when they explicitly requested a non-mutating run.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

When AI classification is enabled, the code sends email subject and body/snippet content to a configured external OpenAI-compatible API. Email content commonly contains personal, financial, or account data, so transmitting it off-system without explicit disclosure, consent, or data-handling controls creates a real privacy and compliance risk.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The prompt interpolates untrusted email subject/body directly into the model instruction block, so a crafted email can include natural-language instructions that try to override the classifier prompt and force misclassification. While this does not directly execute code, it can undermine business workflow triage, suppress urgent messages, or manipulate prioritization decisions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module description and user-facing messages are written exclusively in Chinese, and generated notification text is hardcoded in Chinese throughout the file. There is no indication that the skill is intentionally restricted to a Chinese-speaking or China-specific deployment, nor any option for user language selection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code sends email-derived content to an external Feishu webhook endpoint without any built-in consent, notice, or data-minimization control. In a mail-handling skill, subjects, senders, summaries, and urgency indicators can contain sensitive business or personal data, so silent third-party transmission creates a real privacy and compliance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The direct user-message API path transmits email-derived content plus a recipient identifier to Feishu's external API with no explicit warning or approval workflow. This expands disclosure risk because message content and routing metadata are sent outside the local environment and could violate data-handling expectations or policy.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The single-email push routine constructs messages containing sender, subject, date, summary, category, and optional reply suggestions, then transmits them to Feishu recipients. Because these fields are derived from potentially sensitive customer email, this is a concrete exfiltration path to external parties or overly broad internal audiences if webhook/user targets are misconfigured or compromised.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The daily digest aggregates multiple emails and sends subjects, senders, and categories in a batch to Feishu, increasing the blast radius of a single outbound message. Bulk summaries amplify exposure because one push can disclose many customers' or incidents' details to unintended recipients, making misconfiguration or unauthorized access more damaging.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code performs state-changing IMAP operations by setting or clearing the \Seen flag, which affects mailbox state and can alter how messages are presented to the user. Although the methods have docstrings, there is no user-facing disclosure, confirmation, or warning around this potentially surprising modification of user data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 59)May include surrounding context.

md
self.provider = ai_config.get("provider", "openai")
        self.api_key = ai_config.get("api_key", "")
        self.model = ai_config.get("model", "gpt-4o-mini")
        self.base_url = ai_config.get("base_url", "https://api.openai.com/v1")
        self.max_tokens = ai_config.get("max_tokens", 1000)
        self.temperature = ai_config.get("temperature", 0.7)
        self.timeout = ai_config.get("timeout", 30)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/reply_generator.py (reported line 40)May include surrounding context.

python
self.provider = ai_config.get("provider", "openai")
        self.api_key = ai_config.get("api_key", "")
        self.model = ai_config.get("model", "gpt-4o-mini")
        self.base_url = ai_config.get("base_url", "https://api.openai.com/v1")
        self.max_tokens = ai_config.get("max_tokens", 1000)
        self.temperature = ai_config.get("temperature", 0.7)
        self.timeout = ai_config.get("timeout", 30)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module sends email-derived content, including sender, subject, category, and up to 2000 characters of body text, to an external LLM service without any in-function consent gate, redaction step, or user-facing disclosure. Because emails often contain sensitive personal, business, or confidential data, this creates a real privacy and data-handling risk if operators use the feature without explicit awareness or authorization.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

The README is written entirely in Chinese and introduces the assistant in Chinese, while the skill itself claims multilingual reply generation. There is no statement that the skill is intentionally China-market-only or that users may opt into another interface language, which may conflict with language/locale choice expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The multilingual support section states '中文 (zh) | 默认', which establishes a default language preference in the skill's behavior. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the user is clearly offered a choice or the locale constraint is justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

Natural-language strings such as the module description, CLI description, and report text are all Chinese, with no indication that users can choose another language. This can violate language/locale policy when a skill forces one language by default without offering an opt-in or selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The natural-language descriptions, labels, and prompts in this file are presented in Chinese only, including the class/module description and AI prompt text. Under the stated policy, forcing a specific language without user opt-in or justification can be a language/locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Docstrings and user-visible messages such as connection and fetch errors are written in Chinese, which imposes a specific language on users without any opt-in or fallback. Under the language/locale policy, forcing a single language without choice can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The prompt explicitly instructs the model to write in the selected language (用{lang_name}撰写), and the API defaults to Chinese when no language is specified. This creates a locale/language constraint without any built-in user choice or opt-in at the point of generation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.