T09 · Insecure Skill Coding Practices
- Location
SKILL.md:37- Finding
API Key Exposed Through Documented Shell Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill performs the advertised trade-statistics queries, but it handles API keys and billing-related actions in ways users should review carefully before installing.
Install only if you are comfortable giving the skill access to an Upkuajing API key and paid account functions. Do not print or paste the contents of `~/.upkuajing/.env`; use a redacted presence check or platform secret storage instead, restrict the file to owner-only permissions, and treat recharge-order and exception-reporting actions as operations that need explicit review.
SKILL.md:37API Key Exposed Through Documented Shell Output
scripts/auth.py:63API Key File Created Without Explicit Owner-Only Permissions
requirements.txt:1Security-Sensitive HTTP Dependency Is Not Fully Pinned
The skill's documented purpose is analytics, yet it also instructs the agent to perform exception reporting with request identifiers and contextual metadata to the platform. Hidden telemetry/reporting behavior expands data flows beyond the user's apparent request and may leak operational or user-related context to a third party.
The skill's documented purpose is analytics, yet it also instructs the agent to perform exception reporting with request identifiers and contextual metadata to the platform. Hidden telemetry/reporting behavior expands data flows beyond the user's apparent request and may leak operational or user-related context to a third party.
The skill's documented purpose is analytics, yet it also instructs the agent to perform exception reporting with request identifiers and contextual metadata to the platform. Hidden telemetry/reporting behavior expands data flows beyond the user's apparent request and may leak operational or user-related context to a third party.
The skill explicitly instructs reading a credential file from the user's home directory using a shell command. Encouraging direct access to ~/.upkuajing/.env exposes secrets to the agent runtime and creates a clear path for accidental disclosure, logging, or misuse of the API key.
本技能需要API密钥。API密钥存储在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
The skill directs the workflow around checking for a secret in a local .env file and automatically saving newly created API keys there. This normalizes local secret handling by the agent and increases the risk of unauthorized file writes, insecure storage, or exposing credentials across sessions and tools.
### **API密钥未设置**
首先检查 `~/.upkuajing/.env` 文件中是否有 UPKUAJING_API_KEY;
如果未设置,请让用户选择:
1. 用户已有密钥:用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有密钥:通过界面申请(`auth.py --new_key`),新密钥会自动保存到 ~/.upkuajing/.env
等待用户选择;
The skill asks the agent to determine whether UPKUAJING_API_KEY exists in a local secret file and supports user-supplied insertion into that file. In the context of an agent skill, credential discovery and modification are especially sensitive because they can expose secrets, persist attacker-influenced values, or enable later unauthorized API usage.
首先检查 `~/.upkuajing/.env` 文件中是否有 UPKUAJING_API_KEY;
如果未设置,请让用户选择:
1. 用户已有密钥:用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有密钥:通过界面申请(`auth.py --new_key`),新密钥会自动保存到 ~/.upkuajing/.env
等待用户选择;
### **账户充值**
The file implements API key provisioning, account lookup, and payment-related actions even though the skill is presented as a trade-area statistics/analysis capability. This capability mismatch increases the risk of deceptive scope, unexpected credential handling, and financial operations being exposed to users or agents that only expected data-query behavior.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
The code writes a newly issued API key into a plaintext .env file under the user directory, which can expose credentials to other local processes, backups, or accidental disclosure if file permissions are weak. In an agent-distributed skill, persisting secrets this way without explicit permission hardening is risky because the skill also reaches out to remote account and payment endpoints.
"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")
Creating recharge/payment orders is a financial operation unrelated to customs-area statistics and materially expands the attack surface. In an agent skill context, unexpected payment initiation can enable abuse, user confusion, or unauthorized monetization workflows if invoked by mistake or through prompt/automation chaining.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
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'
# 日志开关
The skill declares executable behaviors that can access environment variables, local files, and remote services, but it does not declare any explicit tool scope or permission boundaries. This increases the chance that a host agent invokes the skill with broader capabilities than users expect, enabling unintended credential exposure, filesystem access, or network actions.
This markdown file declares invocation triggers in the description, and several phrases such as “区域贸易分析”, “全球贸易情报”, and “供应商市场覆盖” are broad natural-language expressions rather than narrowly scoped commands. Because the trigger list does not define boundaries or negative examples, the skill may be invoked for ordinary trade-analysis requests beyond this specific customs company area stats function.
The documentation explicitly instructs callers to transmit request parameters, response payloads, and exception context to an error-reporting endpoint. Even though it states that sensitive fields are 'automatically desensitized,' it does not define the redaction scope, guarantee complete coverage, or warn operators not to include secrets, personal data, or proprietary business data in free-form fields such as context. In a trade/customs analytics skill, these payloads may contain commercially sensitive shipment details, identifiers, or operational metadata, creating a real data leakage risk through telemetry.
This code file contains user-facing natural language entirely in Chinese, including the module description and command help text, with no indication that language is configurable or region-limited. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation.
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.
pass # 如果读取失败,继续执行
# 不需要认证申请新密钥
response = make_request('/agent/auth/create', {}, require_auth=False)
# 检查是否申请成功
if response.get('code') != 0:
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.
pass # 如果读取失败,继续执行
# 不需要认证申请新密钥
response = make_request('/agent/auth/create', {}, require_auth=False)
# 检查是否申请成功
if response.get('code') != 0:
Account information and pricing queries are outside the reasonable functional scope of a trade-statistics skill and expose administrative/business metadata to callers. While less severe than payment creation, this still violates least functionality and can leak sensitive operational details or facilitate enumeration of the service account.
The module title and all user-facing messages/comments in this file are written only in Chinese, which effectively imposes a specific language on users and maintainers. Under the stated policy, a language restriction should either offer user choice or be clearly documented as a justified region-specific constraint, which is not present here.
The overall skill manifest claims the skill queries customs trade regional statistics and analyzes global market coverage. In contrast, this file's code and module docstring are dedicated to reporting agent/skill invocation exceptions to a platform service, which does not perform any customs-company-area statistical query or analysis behavior.