other
- Location
scripts/check_emails.py:121- Finding
OpenAI API Credential Transmitted to an Unrelated Hard-Coded Validation Service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This email assistant is not clearly malicious, but it warrants Review because it handles sensitive mailbox data and includes under-disclosed external sharing plus unrelated token-validation behavior.
Review before installing in any real mailbox. Use only an app-specific mailbox password, avoid sensitive or regulated inboxes unless your organization approves the AI and Feishu data flows, do not rely on --dry-run to prevent pushes, and avoid setting up cron until the token verification, data-sharing disclosure, endpoint controls, and dependency list are fixed.
scripts/check_emails.py:121OpenAI API Credential Transmitted to an Unrelated Hard-Coded Validation Service
scripts/reply_generator.py:114Untrusted Email Content Is Inserted Directly into LLM Prompts
scripts/feishu_pusher.py:129Unrestricted Configurable Endpoints Can Receive Sensitive Email Data
scripts/requirements.txt:1Unnecessary and Unpinned Third-Party Dependencies Create Supply-Chain Risk
The CLI advertises '--dry-run' as a check-only mode, but the flag is never used to suppress side effects. As written, running with '--dry-run' still allows Feishu push operations via process_emails(), which can leak email-derived content or trigger production notifications when the user explicitly requested a non-invasive run.
The listing states that the skill fetches mailbox contents, classifies email content with AI, and pushes alerts/summaries to Feishu, but it does not clearly warn users that sensitive email data may be transmitted to third-party AI and messaging services. This creates a real privacy and compliance risk because users may configure the skill without informed consent about external data sharing, potentially exposing customer PII, credentials, or confidential business communications.
The README explicitly describes pulling mailbox contents, generating AI-based classifications and replies, and pushing summaries to Feishu, but it does not clearly warn users that potentially sensitive email content may be transmitted to third-party AI and messaging services. This creates a real privacy and compliance risk because operators may deploy it without understanding that customer communications and personal data could leave their environment.
The configuration instructs users to send data to an external AI API endpoint, and in this skill's context that data likely includes mailbox content and generated summaries. This is dangerous because customer emails may contain sensitive personal, commercial, or regulated information that is then transmitted to a third party without any documented minimization, redaction, or approval controls.
provider: "openai" # or "claude", "deepseek" api_key: "sk-xxxx" # API key model: "gpt-4o-mini" # Model to use base_url: "https://api.openai.com/v1" # API address (for self-hosted) max_tokens: 1000 temperature: 0.7
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.
crontab -e
# Add the following line:
# 0 * * * * cd /path/to/scripts && python check_emails.py >> /var/log/email_assistant.log 2>&1
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.
crontab -e
# Add the following line:
# 0 * * * * cd /path/to/scripts && python check_emails.py >> /var/log/email_assistant.log 2>&1
The skill processes mailbox contents and explicitly integrates both external AI APIs and Feishu push notifications, but the description does not clearly warn users that email bodies and potentially sensitive customer data may be transmitted to third-party services. This creates a real privacy and compliance risk because operators may enable the skill without informed consent, exposing personal, financial, or business-sensitive information outside the mailbox provider.
The skill explicitly processes mailbox contents with external LLM APIs and pushes email-derived information to Feishu, but the listing does not give a clear privacy warning or explain what data leaves the mailbox environment. This can cause users to unknowingly transmit sensitive customer communications, personal data, or confidential business content to third-party services, increasing legal, compliance, and data leakage risk.
This email-processing script contains unrelated external token-verification logic that sends a provided API key to a third-party endpoint and also falls back to reading OPENAI_API_KEY from the environment. In the context of an email assistant, this expands the trust boundary, introduces secret-handling and outbound-network behavior unrelated to core mail processing, and could disclose credentials or create hidden dependencies users do not expect.
Unread email contents are forwarded to external AI classification/reply-generation components and may also be summarized to Feishu without an explicit consent, warning, or data-handling notice in this script. In an email-assistant context this is especially sensitive because messages commonly contain personal, financial, contractual, or authentication information, so silent transmission increases privacy and compliance risk.
Natural-language strings throughout the file, including the module description and the AI prompt, assume Chinese output and labeling by default. The policy allows locale constraints only when justified or user-selectable, but this file does not offer opt-in language selection or document a justified region-specific limitation.
When AI classification is enabled, the code sends the email subject and part of the body/snippet to an external OpenAI-compatible API endpoint. Email content often contains personal, financial, or account-related data, so transmitting it off-box without explicit notice, consent, data-minimization controls, or trust restrictions can create a confidentiality and compliance risk, especially because the endpoint is configurable and may be third-party or attacker-controlled.
L217-L218上方上下文延续了前面基于优先级进行分类的设计,但这里实际使用 max(match_counts.items(), key=lambda x: x[1]) 按命中次数选择类别,而不是按优先级选择。该实现与同文件 classify() 中“最高优先级匹配”的行为不同,会导致文档/注释表达的分类意图与实际代码执行逻辑发生偏离。
The push_email path packages sender, subject, date, summary, and optional reply suggestion into message content and sends it to Feishu via webhook or API. While the code logs success/failure, it does not disclose to the user that email-derived data will be sent to an external service, which is a privacy-relevant network transmission.
The daily digest constructs and transmits a report containing counts, categories, subjects, and senders for up to 10 emails to Feishu. This is a safety- and privacy-relevant network operation, but the code provides no warning or confirmation that user email data will be shared externally.
The connect method opens an IMAP connection and logs in with the configured username and password, which is a network operation involving credentials. While there is minimal error logging, there is no confirmation prompt or explicit user-facing warning in comments/docstrings that this skill will transmit mailbox credentials and access email contents.
The _fetch_email method retrieves RFC822 content, parses message headers and body, and returns the raw email bytes alongside extracted content. This is a privacy-sensitive network/data access behavior, but the code provides no explicit disclosure beyond internal method names and generic docstrings.
The documentation states '用户确认后再发送,安全可控', which asserts a safety property about sending behavior. In the implementation, the module generates replies, modifies them via AI, and builds a preview with a mailto link, but there is no actual send path or enforcement mechanism proving that sending can only occur after confirmation.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
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)
The code sends email sender, subject, category, and body content to an external AI provider without any explicit consent, warning, redaction, or policy check in this path. If emails contain personal, confidential, or regulated data, this can cause unintended third-party disclosure and compliance violations.
The README states that reply suggestions are generated in specific languages '(EN/JP/KR)' but does not indicate that the user can choose language or opt in to locale behavior. Under the language/locale policy rule, constraining output language without explicit user choice can be a natural-language policy issue unless clearly justified.
Natural-language strings in the docstring, CLI help, logs, and generated report are consistently Chinese, and the file does not indicate that users can choose another language. Under the stated policy, forcing a specific language without user opt-in is a locale-policy violation unless clearly justified as region-specific.
The initializer reads an API key from configuration and later uses it for external network access, but the file provides no warning or documentation that the skill consumes sensitive credentials. Under the code-file criteria, access to credentials should have some visible disclosure unless clearly covered elsewhere.
The module-level documentation is written entirely in Chinese and presents the skill interface and purpose in that language only. Under the stated policy, language-specific behavior or presentation should offer user choice or be clearly justified as region-specific.
The inline comment says "ALL 会获取所有,但可以后续过滤 UNSEEN" (ALL would fetch all and then filter UNSEEN later), but the implemented search criterion is directly 'UNSEEN'. This is an active contradiction between the comment and the code's behavior, though it does not materially expand capability.
No suspicious patterns detected.