Back to skill

Security audit

支持批量群发企业营销邮件,支持追踪每一封邮件的发送、到达、打开、已阅、回复多种状态;提供企业域名邮箱,帮助外贸公司、外贸企业、出口商、采购代理、销售团队触达决策者、轻松邮件群发,并分析邮件打开率与点击率。在外贸获客、企业出海、海外获客中提供强大的批量营销能力,适用于外贸开发信、跨境电商邮件营销与销售获客。

Security checks for vulnerabilities and agentic risk

Overview

This email skill is mostly aligned with its stated purpose, but it handles API keys and billing-related actions in ways users should review carefully before installing.

Install only if you are comfortable with this skill sending email through the Upkuajing API, creating payment/recharge flows, and storing an API key under `~/.upkuajing`. Do not print or paste the `.env` file contents, avoid passing API keys as command-line arguments, review any error report before approving it, and prefer a restricted environment or secret manager for the API key.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:105
Finding
Credential File Contents Are Explicitly Printed## Vulnerability Details **File Location**: `SKILL.md`, lines 105-107 **Vulnerability Type**: Unnecessary credential disclosure **Risk Level**: High ### Vulnerable Code Snippet ```bash cat ~/.upkuajing/.env ``` The surrounding instructions state that this file contains the API key and direct the operator or Agent to display it. ### Technical Analysis The Skill only needs to determine whether `UPKUAJING_API_KEY` is configured and then read that specific value internally for authentication. Printing the entire credential file is not required for email sending, task retrieval, or account management. Displaying the file can expose the API key through: - Agent conversation context and execution records - Terminal output and transcripts - Screen recordings or shared terminal sessions - CI/CD logs - Remote administration logs - Diagnostic bundles containing command output The implementation already includes an internal credential loader in `scripts/common.py`, so direct display of the secret provides no necessary functional benefit and exceeds minimum safe credential access. ### Attack Path 1. A user or Agent follows the Skill instructions and executes the command. 2. The API key is written to terminal output. 3. The output is retained in an Agent transcript, shell session recording, CI log, or support bundle. 4. An attacker with access to that record extracts the Bearer token. 5. The attacker uses the token against the platform API. 6. The attacker can submit email jobs, retrieve campaign and recipient tracking records, inspect account information, or initiate payment-order creation within the permissions associated with the key. ### Impact Assessment Compromise exposes the authenticated capabilities of the affected platform account. Potential impact includes unauthorized paid email submission, access to recipient email addresses, disclosure of message subjects and content, access to delivery/open/click tracking information, and unauthorized account opera ...[truncated 6 chars]
Remediation
## Remediation Suggestions - Remove the instruction to print `~/.upkuajing/.env`. - Test only whether the required variable is present, without displaying its value. - Prefer protected environment-variable injection or an operating-system secret manager. - If file-based storage remains necessary, read only the named key internally. - Redact API keys from all terminal output, exception messages, diagnostic data, and Agent transcripts. - Add documentation warning users never to paste API keys into conversations or command output. - Rotate any key that may already have been exposed through this instruction.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auth.py:70
Finding
API Key Is Written Without Explicitly Restrictive File Permissions## Vulnerability Details **File Location**: `scripts/auth.py`, lines 70-74 **Vulnerability Type**: Insecure plaintext secret storage **Risk Level**: High ### Vulnerable Code Snippet ```python try: with open(env_file, 'w', encoding='utf-8') as f: f.write(f"{API_KEY_ENV}={api_key}\n") except IOError as e: ``` ### Technical Analysis The code stores a reusable Bearer token in plaintext using the default process umask. It does not explicitly ensure that: - The `~/.upkuajing` directory has mode `0700` - The credential file has mode `0600` - An existing file has safe ownership and permissions - The destination is not a symbolic link - The update is performed atomically Consequently, the effective permissions depend on host configuration. Under a permissive umask or unsafe pre-existing filesystem state, another local user or process may be able to read the token. Opening the path with ordinary write mode also follows symbolic links and truncates an existing target. Credential storage is necessary for the declared authenticated functionality, but storage without explicit access controls exceeds the minimum privilege and protection requirements for a long-lived API key. ### Attack Path 1. The victim runs `python scripts/auth.py --new_key`. 2. The platform returns a new API key. 3. The script creates or replaces `~/.upkuajing/.env` using default filesystem permissions. 4. A local attacker, compromised process, backup collector, or incorrectly configured shared account reads the file. 5. The attacker extracts the API key. 6. The attacker reuses it remotely to access the authenticated API capabilities. Where the credential path is replaceable with a symbolic link, an attacker with sufficient access to the parent directory may also redirect the write to another user-accessible target. ### Impact Assessment A stolen key can authorize email submission and access to account-scoped campaign data, recipient addresses, email content, and engagement tracking ...[truncated 130 chars]
Remediation
## Remediation Suggestions - Create `~/.upkuajing` with mode `0700`. - Create the credential file atomically with mode `0600`, such as by using `os.open` with restrictive flags and permissions. - Validate that the directory and file are owned by the current user. - Reject symbolic links and unexpected non-regular files. - Correct unsafe permissions on an existing credential file before reading it. - Use a temporary file in the same directory, apply restrictive permissions, flush it, and atomically replace the destination. - Prefer an operating-system keyring or secret manager over a plaintext environment file. - Never include any portion of the key in status or error messages.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mail_send.py:120
Finding
API Keys Can Be Passed Through Process Command-Line Arguments## Vulnerability Details **File Locations**: - `scripts/mail_send.py`, lines 120-124 - `scripts/mail_task_list.py`, lines 102-106 - `scripts/mail_task_record_list.py`, lines 110-114 **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: High ### Vulnerable Code Snippets Each affected script declares a command-line API-key option: ```python parser.add_argument( '--api_key', type=str, ``` The resulting value is passed into the authenticated operation. For example, the email sender uses: ```python result = send_email( send_name=args.send_name, email_name=args.email_name, subject=args.subject, content=args.content, reply_email=args.reply_email, emails=emails, api_key=args.api_key ) ``` Equivalent argument handling is present in both task-query scripts. ### Technical Analysis Secrets passed as command-line arguments may be exposed through: - Shell history - Process inspection interfaces - System audit logs - Job schedulers and orchestration metadata - CI/CD command logs - Agent tool-call transcripts - Crash and diagnostic reports The project already supports loading the API key from a protected environment variable or credential file. Therefore, exposing a separate command-line credential channel is unnecessary and increases the number of places where the secret can persist. ### Attack Path 1. A user or Agent invokes an affected script with the API key in the command line. 2. The complete command is recorded in shell history, Agent execution metadata, process telemetry, or an automation log. 3. A local user or log reader retrieves the recorded command. 4. The attacker extracts the key from the `--api_key` value. 5. The attacker authenticates to the remote platform using the stolen token. 6. The attacker performs operations authorized for the victim’s account. ### Impact Assessment The exposed token may provide access to paid email sending, campaign history, recipient-level delivery and ...[truncated 168 chars]
Remediation
## Remediation Suggestions - Remove the `--api_key` option from all affected scripts. - Load credentials only from a protected environment variable, secret manager, or restricted credential file. - If interactive entry is unavoidable, use a no-echo prompt and do not persist the entered value. - Ensure automation systems inject the secret through their protected secret facilities. - Add redaction rules for the API-key name and Bearer-token patterns in logs and telemetry. - Warn users not to place credentials in shell commands. - Rotate keys previously used through command-line arguments where command history or execution logs may have been retained.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Dependency Is Unbounded and Lacks Integrity Pinning## Vulnerability Details **File Location**: `requirements.txt`, line 1 **Vulnerability Type**: Non-reproducible and integrity-unverified dependency resolution **Risk Level**: Medium ### Vulnerable Code Snippet ```text httpx>=0.23.0 ``` The documented installation command installs directly from this requirements file: ```bash pip install -r requirements.txt ``` ### Technical Analysis The lower-bound-only dependency declaration allows any present or future `httpx` release satisfying the constraint. No lockfile, exact version, package hashes, or trusted-index policy is supplied. This does not establish that the current dependency is malicious. It does mean that installation behavior is not reproducible and that a future compromised, malicious, or incompatible release could be selected without a source-code change to the Skill. Because the dependency executes in the same Python environment as the Skill, it can potentially access process environment variables, the API-key file, email content, recipient addresses, API responses, and the network. ### Attack Path 1. A user follows the installation instructions. 2. The package resolver selects the newest release satisfying the broad version constraint. 3. A compromised or otherwise unsafe compatible release is downloaded from the configured package source. 4. Package code runs during installation or when imported by the Skill. 5. The compromised dependency reads credentials or email data available to the process. 6. The data is modified, misused, or transmitted to an attacker-controlled destination. ### Impact Assessment A dependency compromise could obtain the full privileges of the user running the Skill. Relevant assets include the platform API key, email bodies, recipient lists, task history, recipient tracking records, and any other files accessible to that user. The impact may extend beyond the Skill if installation occurs in a shared or privileged Python environment.
Remediation
## Remediation Suggestions - Pin `httpx` to a specifically reviewed version. - Maintain a lockfile containing all transitive dependency versions. - Generate and require cryptographic hashes for downloaded distributions. - Configure installation to use an approved package index. - Review and update pinned dependencies through a controlled security-update process. - Install the Skill in an isolated virtual environment under a non-privileged account. - Add automated dependency vulnerability and provenance scanning.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/error_report.py:13
Finding
Error Reports Can Transmit Unsanitized Request and Response Data## Vulnerability Details **File Locations**: - `scripts/error_report.py`, lines 13-31 - `references/skill-error-report-api.md`, lines 25-26 **Vulnerability Type**: Insufficient client-side minimization of diagnostic data **Risk Level**: Medium ### Vulnerable Code Snippet ```python def report_error(params: dict) -> dict: params.setdefault('skillId', get_skill_name()) params.setdefault('skillVersion', get_skill_version()) for field in ('skillId', 'skillVersion', 'requestId', 'requestPath', 'context'): if not params.get(field): sys.exit(1) response = make_request('/agent/skill/error/report', params) return response ``` The documented schema permits the supplied object to contain complete request parameters and response data. The client sends the caller-provided dictionary without recursively filtering or minimizing those fields. ### Technical Analysis The documentation states that sensitive fields are redacted by the server. Server-side redaction occurs only after the raw report has crossed the client’s trust boundary and reached the remote endpoint. The client does not: - Allowlist permitted report fields - Remove authorization values - Redact nested secrets - Exclude email bodies or recipient lists - Limit personal data in diagnostic context - Preview the final report before submission - Programmatically enforce or record user confirmation The Skill instructions require user approval before invoking error reporting, which reduces accidental reporting when followed. However, the executable itself accepts and sends the supplied object directly, so safety depends entirely on the caller and remote server. ### Attack Path 1. An API request fails or produces an unexpected response. 2. A caller constructs a diagnostic object containing raw request parameters, response data, or exception context. 3. Those fields include email addresses, message content, account information, or a credential copied into diagnostic contex ...[truncated 743 chars]
Remediation
## Remediation Suggestions - Define a strict allowlist of report fields. - Recursively redact API keys, authorization headers, cookies, tokens, email addresses, and other personal data before transmission. - Exclude full email bodies and recipient lists by default. - Truncate diagnostic context and reject unexpectedly large nested values. - Display a redacted preview identifying exactly what will be transmitted. - Require explicit confirmation immediately before submission. - Record only a non-sensitive consent timestamp or event identifier. - Do not rely solely on server-side redaction. - Document diagnostic retention, access controls, and deletion procedures.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Undeclared version-check network requests and local cache writes are materially different from the advertised email utility behavior. Hidden outbound requests and filesystem writes are dangerous because they expand the trust boundary, create covert telemetry channels, and may expose environment or usage metadata without clear authorization.

Credential Access

High
Category
Privilege Escalation
Content
使用此技能需要API密钥。API密钥保存在 `~/.upkuajing/.env` 文件中:
```bash
cat ~/.upkuajing/.env
```
**文件内容示例**:
```
Confidence
96% confidence
Finding
The skill explicitly instructs reading the API key from ~/.upkuajing/.env and even shows using cat to display the file contents. In an agent context, prompting or enabling direct secret-file access is dangerous because it can expose credentials to the model, logs, transcripts, or downstream tools beyond the minimum needed for authentication.

Credential Access

High
Category
Privilege Escalation
Content
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
Confidence
97% confidence
Finding
The skill instructs checking for a local API key and, if absent, invoking a flow that automatically applies for and saves a new key to ~/.upkuajing/.env. This is dangerous because it combines credential discovery, issuance, and persistence in a local file, increasing the chance of unauthorized credential creation, accidental exposure, and poor secret lifecycle controls.

Credential Access

High
Category
Privilege Escalation
Content
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;

### **账户充值**
Confidence
97% confidence
Finding
The documented workflow normalizes local inspection and modification of ~/.upkuajing/.env for API key management. In a tool-enabled agent environment, this broadens credential-access behavior from passive use of injected secrets to active file-based secret handling, which raises the risk of leakage, tampering, and persistence of sensitive tokens on disk.

Credential Access

High
Category
Privilege Escalation
Content
"""
    申请新的 API 密钥。
    """
    # 检查是否已存在 .env 文件和 API key
    env_file = UPKUAJING_ENV_FILE

    if env_file.exists():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""
    申请新的 API 密钥。
    """
    # 检查是否已存在 .env 文件和 API key
    env_file = UPKUAJING_ENV_FILE

    if env_file.exists():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""
    申请新的 API 密钥。
    """
    # 检查是否已存在 .env 文件和 API key
    env_file = UPKUAJING_ENV_FILE

    if env_file.exists():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""
    申请新的 API 密钥。
    """
    # 检查是否已存在 .env 文件和 API key
    env_file = UPKUAJING_ENV_FILE

    if env_file.exists():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""
    申请新的 API 密钥。
    """
    # 检查是否已存在 .env 文件和 API key
    env_file = UPKUAJING_ENV_FILE

    if env_file.exists():
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"envFilePath": str(env_file)
        }

    # 保存到 .env 文件
    try:
        with open(env_file, 'w', encoding='utf-8') as f:
            f.write(f"{API_KEY_ENV}={api_key}\n")
Confidence
82% confidence
Finding
The function stores a freshly issued API key in a plaintext .env file under the user's home directory without any visible permission hardening. If the file inherits permissive filesystem defaults or is later exposed through backups, other local users, or tooling, the API credential could be stolen and abused.

Credential Access

High
Category
Privilege Escalation
Content
except IOError as e:
        return {
            "success": False,
            "message": f"API密钥申请成功,但保存到 .env 文件失败:{str(e)}。\n请手动设置环境变量 {API_KEY_ENV}。",
            "envFilePath": str(env_file)
        }
Confidence
89% confidence
Finding
On error, the code returns the full environment file path and elsewhere partially discloses the existing key prefix in user-facing messages. While not full credential exfiltration, leaking secret-storage locations and key fragments increases exposure and can aid local reconnaissance or accidental disclosure through logs and support channels.

Credential Access

High
Category
Privilege Escalation
Content
API_BASE_URL = "https://openapi.upkuajing.com"
API_KEY_ENV = "UPKUAJING_API_KEY"
UPKUAJING_DIR = Path.home() / '.upkuajing'
UPKUAJING_ENV_FILE = UPKUAJING_DIR / '.env'
UPKUAJING_LOGS_DIR = UPKUAJING_DIR / 'logs'

# 日志开关
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares capabilities that imply environment access, local file read/write, and network use, but it does not declare any explicit tool scope or permissions boundary. This is dangerous because the agent may perform sensitive operations such as reading API keys from local files and contacting remote services without transparent least-privilege constraints.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
The manifest emphasizes email sending/tracking, but the documentation also instructs billing-related account management actions such as recharge flows. This matters because financially sensitive behavior is materially different from routine messaging functionality and should not be hidden under a narrower description.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The documentation says the skill consists of three scripts for sending and querying email tasks, yet later introduces additional privileged operations such as key issuance, recharge ordering, account inspection, and error reporting. This inconsistency is dangerous because reviewers and users may underestimate the skill's actual authority and approve it with insufficient scrutiny.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
L198 要求“禁止输出技术参数格式,应将其转换为自然语言”,结合整份技能文档完全以中文编写并面向中文交互,存在默认强制单一语言/语言风格的倾向,但未说明可根据用户语言偏好切换。按照语言/locale 政策,若未提供用户选择或明确 opt-in,强制特定语言可能构成自然语言政策问题。

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The document instructs agents to upload request parameters, response payloads, and exception context to an error-reporting endpoint. Even though it claims sensitive fields are automatically redacted, it does not define what is considered sensitive, require minimization, or warn users that business/customer data and stack traces may be transmitted off the primary workflow, creating a real risk of privacy leakage and over-collection.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
pass  # 如果读取失败,继续执行

    # 不需要认证申请新密钥
    response = make_request('/agent/auth/create', {}, require_auth=False)

    # 检查是否申请成功
    if response.get('code') != 0:
Confidence
75% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
pass  # 如果读取失败,继续执行

    # 不需要认证申请新密钥
    response = make_request('/agent/auth/create', {}, require_auth=False)

    # 检查是否申请成功
    if response.get('code') != 0:
Confidence
80% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/common.py:197

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/mail_send.py:31

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/mail_task_list.py:29

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/mail_task_record_list.py:30