Back to skill

Security audit

端到端 B2B 触达工具集,整合批量冷邮件、全球短信、Google Maps 商户采集与联系方式校验于一体。支持企业批量冷邮件群发与全球短信群发(双向可回复),并监控发送、送达、打开、回复等完整送达状态;按国家、地区、半径、行业与关键词采集Google Maps 商户数据,批量获取商家名称、地址与联系方式;触达前校验手机号(座机、手机、是否注册WhatsApp)、邮箱与域名,降低退信率、清洗 CRM 联系人列表。帮助出口商、贸易商、采购代理与全球销售团队开展跨境触达活动--采集、校验、触达、监控一站式完成,适用于 B2B冷启动外联与海外客户开发。

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its B2B outreach purpose, but it handles API keys and sensitive outreach data in ways users should review carefully before installing.

Install only if you are comfortable giving this skill an API key that can access billable outreach, account, validation, and task data. Do not let the agent print or paste `~/.upkuajing/.env`; prefer an environment variable or protected secret store, rotate any exposed key, confirm every send/search/validation action before it runs, and use only authorized contact lists with appropriate consent, opt-out, and compliance review.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:140
Finding
API Credential Disclosure Through Skill Instructions## Vulnerability Details **File Location**: `SKILL.md`, lines 140-151 **Vulnerability Type**: Unnecessary disclosure of a plaintext API credential to the Agent session **Risk Level**: High ### Vulnerable Code ```markdown This Skill requires an API key stored in `~/.upkuajing/.env`: ```bash cat ~/.upkuajing/.env ``` ```text UPKUAJING_API_KEY=your_api_key_here ``` If the API key is not configured, first inspect `~/.upkuajing/.env` for `UPKUAJING_API_KEY`. ``` The quoted text is an English rendering of the original Skill instructions; the command and credential name are unchanged. ### Technical Analysis The instructions direct the Agent to run `cat ~/.upkuajing/.env`. This prints the entire credential file into command output. In an Agent environment, tool output may be copied into the active conversation, model context, execution logs, observability systems, or retained transcripts. Displaying the credential is not required for authenticated requests. The implementation in `scripts/common.py` can retrieve the expected key internally without printing its value. The instruction therefore exceeds the minimum access necessary for the declared functionality. The command also prints every other value that might be added to the same file, not only `UPKUAJING_API_KEY`. ### Attack Path 1. A user asks the Agent to use an authenticated Skill function. 2. The Agent follows `SKILL.md` and executes `cat ~/.upkuajing/.env`. 3. The complete file, including the API key, is returned as tool output. 4. The credential enters the Agent context or associated logs. 5. A party with access to those records can reuse the key against the UpKuaJing API. ### Impact Assessment Disclosure may allow unauthorized authenticated API requests, use of paid services, access to account information, access to email or SMS task records, merchant searches, contact validation, and unauthorized outreach. The precise scope depends on the ser ...[truncated 49 chars]
Remediation
## Remediation Suggestions - Remove the `cat ~/.upkuajing/.env` instruction. - Check only whether the expected variable exists and is nonempty; never print its value. - Prefer an injected process environment or operating-system secret manager over a plaintext file. - If a file fallback remains necessary, provide a helper that returns only a Boolean configuration status. - Ensure error messages never include the key or the contents of the credential file. - Document that users must not paste API keys into chat messages or Agent command arguments.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auth.py:76
Finding
Credential File Created Without Enforced Restrictive Permissions## Vulnerability Details **File Location**: `scripts/auth.py`, lines 76-89 **Vulnerability Type**: Insecure plaintext credential storage permissions **Risk Level**: High ### Vulnerable Code ```python # Ensure ~/.upkuajing exists try: UPKUAJING_DIR.mkdir(parents=True, exist_ok=True) except OSError as e: return { "success": False, "message": f"API key creation succeeded, but directory creation failed: {str(e)}.", "envFilePath": str(env_file) } # Save to the .env file try: with open(env_file, 'w', encoding='utf-8') as f: f.write(f"{API_KEY_ENV}={api_key}\n") ``` The quoted error messages and comments are English renderings of the original source; executable behavior is unchanged. ### Technical Analysis The code stores the API key in plaintext but does not explicitly set the directory to mode `0700` or the file to mode `0600`. Effective permissions are inherited from the host process umask. Under a permissive or misconfigured umask, the directory or file may be readable by other local users. The code also opens the destination by path without first rejecting symbolic links or verifying ownership. If an attacker can manipulate `~/.upkuajing` or `.env`, opening the file with mode `w` may follow a symlink and overwrite another user-writable target. ### Attack Path 1. The user runs `python scripts/auth.py --new_key`. 2. The server returns a newly created API key. 3. The script creates `~/.upkuajing/.env` using default permissions derived from the current umask. 4. On a shared host with permissive permissions, another local account reads the file. 5. The other account reuses the API key for authenticated and potentially billable operations. A secondary local attack is possible if an attacker can pre-create the path as a symlink before the credential is written. ### Impact Assessment A local attacker may obtain the full API credential and perform ope ...[truncated 345 chars]
Remediation
## Remediation Suggestions - Create `~/.upkuajing` with mode `0700` and verify that it is owned by the current user. - Create the credential file atomically with mode `0600`, such as by using `os.open` with `O_CREAT | O_EXCL | O_WRONLY` and an explicit mode. - Apply `chmod(0o600)` to existing files after verifying ownership. - Reject symbolic links by using `O_NOFOLLOW` where supported and by validating the resolved parent directory. - Write to a protected temporary file, flush and synchronize it, and atomically replace the final file. - Prefer a platform secret manager or operating-system credential store when available.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mail_send.py:120
Finding
API Keys Accepted Through Process-Visible Command-Line Arguments## Vulnerability Details **File Location**: `scripts/mail_send.py`, lines 120-124 **Additional Locations**: `scripts/mail_task_list.py:102-106`, `scripts/mail_task_record_list.py:110-114`, `scripts/sms_send.py:91-95`, `scripts/sms_task_list.py:101-105`, and `scripts/sms_task_record_list.py:110-114` **Vulnerability Type**: Secret exposure through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument( '--api_key', type=str, help='API key, optional; defaults to the environment variable' ) ``` The help text is an English rendering of the original source; the option name and behavior are unchanged. ### Technical Analysis Command-line arguments are not an appropriate transport for long-lived credentials. Depending on the operating system and execution environment, arguments may be visible through process inspection tools, shell history, Agent command transcripts, job-control systems, telemetry, audit logs, and error reports. Although environment-based retrieval is already supported, exposing `--api_key` encourages users and Agents to place the secret directly into a command. The same pattern occurs across six email and SMS scripts. ### Attack Path 1. A user or Agent invokes a script with `--api_key SECRET`. 2. The complete command is retained in shell history, an Agent transcript, or process-launch telemetry. 3. While the process runs, another permitted local user may inspect its argument vector. 4. The observer extracts the key and submits authenticated API requests. ### Impact Assessment An exposed key may permit unauthorized email or SMS sending, task-record access, account usage, and other API operations available to that credential. It may also cause direct financial loss through billable requests and reputational or legal harm through unauthorized outreach.
Remediation
## Remediation Suggestions - Remove `--api_key` from all affected command-line interfaces. - Retrieve the credential only from a protected environment, secret manager, or restricted credential file. - If interactive entry is required, use a no-echo prompt and avoid retaining the value after request construction. - Add documentation warning users not to place secrets in chat messages, command lines, or JSON parameters. - Redact known credential patterns from application logs and Agent execution records. - Rotate any key previously supplied through a logged command line.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Dependency Without Integrity Verification## Vulnerability Details **File Location**: `requirements.txt`, line 1 **Related Instruction**: `SKILL.md:25-26` directs users to install this dependency file. **Vulnerability Type**: Open-ended dependency resolution and missing package hashes **Risk Level**: Medium ### Vulnerable Code ```text httpx>=0.23.0 ``` The associated installation instruction is: ```bash pip install -r requirements.txt ``` ### Technical Analysis The lower-bound-only constraint allows any future `httpx` version accepted by the package resolver. The installation therefore is not reproducible and may introduce unaudited behavioral changes or newly added transitive dependencies. No lock file or package hashes are supplied. Package provenance and artifact integrity are consequently delegated entirely to the configured package index and current resolver state. This is an unsafe supply-chain configuration, although the audit found no evidence that `httpx` itself is malicious. ### Attack Path 1. The Agent follows the documented setup command. 2. The package resolver selects a newer, unreviewed release and its current transitive dependency set. 3. A compromised package-index account, malicious mirror, dependency compromise, or future incompatible release supplies unsafe code. 4. Package code executes during installation or later when imported by the Skill. ### Impact Assessment Dependency code executes with the same privileges as the Python process. A compromised dependency could read the API credential, inspect user files available to the process, alter API requests, exfiltrate outreach data, or execute arbitrary code within the user's permission boundary.
Remediation
## Remediation Suggestions - Pin `httpx` to a reviewed exact version. - Lock all transitive dependencies using a reproducible dependency-management tool. - Include cryptographic hashes and install with hash verification. - Review and update the lock file through a controlled dependency-update process. - Install into an isolated virtual environment rather than the global Python environment. - Use a trusted package index and monitor dependencies for security advisories and ownership changes.

other

Note
Location
scripts/version_check.py:95
Finding
Automatic Undocumented Version-Check Telemetry## Vulnerability Details **File Location**: `scripts/version_check.py`, lines 95-105 **Invocation Location**: `scripts/common.py:202` **Vulnerability Type**: Undisclosed network telemetry and installation identifier disclosure **Risk Level**: Low ### Vulnerable Code ```python def check_skill_version(skill_name: str, api_base_url: str) -> Optional[str]: """Call the API to check the latest version.""" try: url = f"{api_base_url}/agent/api/skills/version" headers = {"Content-Type": "application/json"} with httpx.Client(timeout=10.0) as client: response = client.post( url, json={"name": skill_name}, headers=headers ) response.raise_for_status() ``` It is automatically invoked from the common request path: ```python check_and_notify(API_BASE_URL) ``` Comments and the docstring are English renderings of the original source; executable behavior is unchanged. ### Technical Analysis Before normal API requests, the common request function invokes a version check. The check sends the derived Skill name to the platform once per day according to a local cache. `get_skill_name()` obtains this value from `os.path.basename(SKILL_BASE_DIR)`, not from the declared Skill metadata. In generated or temporary installations, the directory basename may contain an opaque installation-specific identifier. The automatic side request is not documented in `SKILL.md`, and no user-facing opt-out is provided. The endpoint does not return executable code, and no remote payload is executed. The issue is limited to unexpected telemetry, privacy, and an additional network side effect. ### Attack Path 1. The user invokes any script that uses `make_request`. 2. `make_request` automatically calls `check_and_notify`. 3. The code derives a name from the installation directory basename. 4. It posts that valu ...[truncated 531 chars]
Remediation
## Remediation Suggestions - Document the automatic version request and the data it transmits. - Make the check opt-in or provide a clearly documented disable setting. - Use the fixed Skill name declared in `SKILL.md` rather than the installation directory basename. - Do not transmit installation paths, generated directory names, user identifiers, or host metadata. - Consider performing version checks only when the user explicitly requests them. - Preserve the current property that version responses are informational only and are never downloaded or executed automatically.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (284)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
代码块的核心功能是“认证管理/计费管理”,属于平台接入与账户运维层能力,而不是声明中的B2B营销触达与数据采集/校验业务能力。虽然注释提到该认证脚本服务于多个原始技能并覆盖邮件、短信、地图搜索、联系方式校验相关技能的定价查询兜底,但当前代码本身并未执行这些业务操作。其实际触发参数(--new_key, --account_info, --new_rec_order, --price_info)也与声明的营销触达类触发词明显不一致。因此描述未准确反映该代码块的实际行为,属于明显不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明描述的是一个面向营销触达的综合工具集,核心用途是邮件、短信、线索采集与联系人校验;而实际代码的唯一功能是向平台报告Skill调用异常,属于内部运维/监控能力。二者主目的完全不同,且代码没有体现任何已声明的业务功能,因此属于明显的描述与行为不一致。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明描述的是一个综合B2B营销触达工具集,核心功能围绕邮件、短信、线索采集和联系方式校验。而实际代码的主功能只是查询地理行政区列表(country/province/city),既没有发送邮件或短信,也没有进行Google Maps商户采集、联系方式校验、CRM清洗或营销活动监控。相反,代码调用的是通用地理信息端点,属于与声明内容明显不同的主要用途,因此构成显著描述-行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
代码的实际功能非常单一,仅限于“发送短信”。虽然声明中包含“全球批量短信”“双向短信回复”等与该脚本部分相关的内容,但整体描述将技能定义为一个覆盖邮件、短信、线索采集、校验、监控和CRM清洗的综合触达工具集。该代码块并未体现这些主要能力,也未显示端到端活动管理、状态监控或数据采集/校验功能。不存在明显的额外未声明危险能力;问题在于声明范围远大于代码实际行为,且主要用途与完整描述不一致,因此应判定为描述与行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明描述的是营销触达与线索采集/校验类能力,但提供的代码与这些功能无关。该代码的主要用途是检查当前skill是否有新版本可升级,属于维护/更新机制,而非邮件、短信、地图采集、联系人校验或CRM清洗。虽然版本检查可被视为辅助基础设施,但当前代码块本身没有体现任何已声明的核心业务能力,因此描述与实际行为存在明显不匹配。

Credential Access

High
Category
Privilege Escalation
Content
本技能需要 API 密钥,存储在 `~/.upkuajing/.env`:
```bash
cat ~/.upkuajing/.env
```
```
UPKUAJING_API_KEY=your_api_key_here
Confidence
96% confidence
Finding
The documentation instructs reading a local secrets file with `cat ~/.upkuajing/.env`, exposing a credential-bearing path and encouraging direct file access to API keys. In a skill with file-read capability, normalizing direct inspection of secret storage increases the risk of credential disclosure to the model, logs, or an unintended user-visible response.

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
"""
    申请新的 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
95% confidence
Finding
The script writes a newly issued API key into a plaintext .env file under the user's home directory. Storing long-lived credentials unencrypted on disk increases exposure to local compromise, accidental backup leakage, or other tools reading the file; in this skill context, the key grants access to account and outbound messaging functions, making subsequent abuse financially and operationally meaningful.

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
89% confidence
Finding
The skill declares capabilities that imply environment access, file read/write, and network operations, but it does not define any explicit tool scope or allowed-tools boundary. In a skill that can send outbound email/SMS, read API keys, and write local files, missing scope restrictions increases the chance of unintended access or abuse if the runtime grants broad defaults.

Vague Triggers

Medium
Confidence
95% confidence
Finding
An overly broad trigger list can cause accidental invocation of a powerful outreach skill in unrelated conversations. In this context, mistaken activation is more dangerous than usual because the skill can initiate billable actions, interact with external APIs, and handle contact data for mass messaging workflows.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This reference documents bulk email sending and exposes fields for recipient lists, message content, reply addresses, and open/click tracking, but provides no warning or constraints around consent, privacy, lawful use, or handling of personal data. In the context of a B2B outreach skill explicitly designed for cold email and campaign tracking, this omission increases the risk of abusive outreach, privacy violations, and non-compliant processing of contact data.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The document instructs agents to send request parameters, response data, and error context to a centralized error-reporting API, which can include sensitive business data, contact details, tokens, stack traces, or message contents. Although it claims sensitive fields are automatically masked, it does not define the masking scope, require data minimization, or warn operators not to include personal or regulated data, which is risky in a B2B outreach skill that handles email, phone, WhatsApp, CRM, and campaign data.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The API reference instructs users to send email address lists and a Bearer authorization token to an external validation service without any warning about third-party data transfer, privacy implications, or credential handling. In a B2B outreach skill, this omission is risky because users may upload customer or prospect contact data and secrets without understanding that personal/business data is leaving their environment and may trigger compliance, consent, or data-handling issues.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
This markdown file presents all user-facing documentation exclusively in Chinese, and it does not indicate that the skill is region-specific or provide any opt-in for language/locale. Under the policy, forcing a specific language without user choice can be a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The module docstring and all user-facing help/messages are written exclusively in Chinese, and the file does not indicate that the skill is China-region-specific or that users may opt into another language. Under the policy, forcing a specific language without user choice or justification is a natural-language policy violation.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
price_info 通过 ORIGINAL_SKILL_NAMES 枚举并合并 email、sms、map 搜索以及手机号/邮箱/域名校验等多个原始技能的价格数据,而不是仅服务当前技能自身。对于一个 B2B 触达工具集而言,跨技能定价聚合不是执行触达、采集或校验的直接必要能力,属于与业务目的弱相关的平台管理能力。

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.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
该文件不仅处理与触达能力相关的认证,还提供创建充值订单和查询开放平台全部接口定价的功能。技能清单描述聚焦于冷邮件、短信、Google Maps采集和联系方式校验,并未声明财务充值或平台级定价管理能力,因此这里存在技能描述与实际行为的语义扩张。

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:196

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

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/sms_send.py:25

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/sms_task_list.py:28

File appears to expose a hardcoded API secret or token.

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