T09 · Insecure Skill Coding Practices
- Location
SKILL.md:37- Finding
API Key Disclosure Through Full Credential File Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does what it claims, but it handles API keys and payment-related account actions in ways users should review carefully before installing.
Review this skill before installing if you use a funded UpKuaJing account. Do not run commands that print `~/.upkuajing/.env`, avoid pasting API keys into chat or logs, and be cautious with `auth.py --new_key` and `auth.py --new_rec_order` because they create persistent credentials and payment-related URLs. Prefer setting the API key through a safer secret mechanism and verify file permissions if you use the local `.env` path.
SKILL.md:37API Key Disclosure Through Full Credential File Output
scripts/auth.py:63API Key Stored Without Explicitly Restrictive File Permissions
requirements.txt:1Unbounded and Unverified Third-Party Dependency Installation
The skill description centers on trade analytics, yet the detected behavior includes remote version checks, local cache reads/writes, and upgrade notifications unrelated to the primary task. While not inherently malicious, undocumented updater/telemetry behavior expands the trust boundary and can introduce unnecessary network and filesystem access paths.
The skill description centers on trade analytics, yet the detected behavior includes remote version checks, local cache reads/writes, and upgrade notifications unrelated to the primary task. While not inherently malicious, undocumented updater/telemetry behavior expands the trust boundary and can introduce unnecessary network and filesystem access paths.
The skill description centers on trade analytics, yet the detected behavior includes remote version checks, local cache reads/writes, and upgrade notifications unrelated to the primary task. While not inherently malicious, undocumented updater/telemetry behavior expands the trust boundary and can introduce unnecessary network and filesystem access paths.
The skill instructs reading the entire ~/.upkuajing/.env file via cat to obtain an API key. Directly accessing and potentially exposing a plaintext credential file is dangerous because it can leak secrets unrelated to the immediate operation and normalize unsafe secret-handling practices.
This skill requires an API key. The API key is stored in the ~/.upkuajing/.env file:
cat ~/.upkuajing/.env
Example file content:
The workflow directs the agent to check for an API key in a local .env file and, if missing, obtain and automatically save a new key there. This combines credential discovery with credential creation and local persistence, increasing the risk of unauthorized secret handling, accidental disclosure, and long-lived plaintext storage.
### **API Key Not Set**
First check if the `~/.upkuajing/.env` file has UPKUAJING_API_KEY;
If UPKUAJING_API_KEY is not set, prompt the user to choose:
1. User has one: User provides it (manually add to ~/.upkuajing/.env file)
2. User doesn't have one: You can apply using the interface (`auth.py --new_key`), the new key will be automatically saved to ~/.upkuajing/.env
Wait for user selection;
The instructions encourage checking a plaintext credential file and saving a newly created API key back into that file automatically. In the context of a trade-analysis skill, this is especially risky because the secret-handling behavior is ancillary to the main purpose and may occur under user expectations of a simple data lookup.
First check if the `~/.upkuajing/.env` file has UPKUAJING_API_KEY;
If UPKUAJING_API_KEY is not set, prompt the user to choose:
1. User has one: User provides it (manually add to ~/.upkuajing/.env file)
2. User doesn't have one: You can apply using the interface (`auth.py --new_key`), the new key will be automatically saved to ~/.upkuajing/.env
Wait for user selection;
### **Account Top-up**
This file implements API-key lifecycle, account lookup, pricing, and recharge-order creation for a skill whose declared purpose is customs-trade trend analysis. While not an exploit by itself, the mismatch expands the skill’s privilege and financial surface beyond user expectations, increasing the chance of misuse, unintended billing actions, and supply-chain abuse.
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 reads an existing .env file, extracts the API key, and includes part of that key in a user-facing message. Even partial secret disclosure can leak identifying material into logs, terminals, screenshots, or telemetry and makes secret handling weaker than necessary.
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
# 读取现有的 .env 文件
try:
with open(env_file, 'r', encoding='utf-8') as f:
content = f.read()
The code writes a newly issued API key into a .env file under the user’s home directory, which is a plaintext storage mechanism unless additional protections are applied. If the file permissions are weak, backed up insecurely, or exposed to other local processes, the credential can be stolen and abused.
"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 capability unrelated to customs-trend analytics and introduces a direct billing action into the skill. If invoked unexpectedly or by a compromised workflow, it could initiate unwanted payment flows, facilitate social engineering, or expose users to fraudulent top-up activity.
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 manifest describes a skill for retrieving monthly customs-trade breakdowns and analyzing seasonal or long-term trade trends by company ID. This file instead collects invocation metadata and sends exception reports to a platform endpoint, which is operational telemetry rather than customs-data analysis behavior.
The skill advertises executable capabilities that include environment access, file read/write, and network use, but it does not declare any explicit tool scope or permissions boundaries. That creates an over-privileged execution model where a consumer cannot easily tell what the skill is allowed to access, increasing the chance of unintended credential/file exposure or network actions.
This markdown file presents all user-facing instructions and API reference text exclusively in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation when no alternative language option or justification is provided.
This code file contains natural-language descriptions and user-facing messages exclusively in Chinese, including the module docstring and CLI help text, with no indication that users may choose another language. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.
API key provisioning is an account-management function that exceeds the declared analytics-only scope of the skill. Bundling credential issuance into a data-analysis skill increases attack surface and can normalize silent credential creation in contexts where users expect read-only analytics behavior.
The function returns multiple end-user status and error messages only in Chinese, and there is no mechanism for locale selection or user opt-in. This can violate language/locale policy because the skill enforces one language for operational messaging.
The explicit require_auth=False setting for API key creation signals a permissive default for a security-sensitive operation. In the context of a skill that should primarily analyze trade data, this expands abuse potential and makes unauthorized credential generation more concerning.
pass # 如果读取失败,继续执行
# 不需要认证申请新密钥
response = make_request('/agent/auth/create', {}, require_auth=False)
# 检查是否申请成功
if response.get('code') != 0:
The explicit require_auth=False setting for API key creation signals a permissive default for a security-sensitive operation. In the context of a skill that should primarily analyze trade data, this expands abuse potential and makes unauthorized credential generation more concerning.
pass # 如果读取失败,继续执行
# 不需要认证申请新密钥
response = make_request('/agent/auth/create', {}, require_auth=False)
# 检查是否申请成功
if response.get('code') != 0:
The manifest describes getting monthly customs-trade breakdowns and analyzing trends, which implies querying and processing data, but this utility module also persists arbitrary outputs and task metadata to local files and per-task directories. Local persistence may be useful for implementation, yet the code exposes a broader task-management and result-storage subsystem than the manifest description suggests.
Detected: suspicious.exposed_secret_literal