T09 · Insecure Skill Coding Practices
- Location
scripts/auth.py:69- Finding
API Key File Is Created Without Explicit Owner-Only Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does the advertised paid customs-data lookup, but it handles API credentials and account/billing actions in ways users should review carefully before installing.
Install only if you are comfortable giving this skill access to your Upkuajing API account and paid API balance. Do not ask the agent to display `~/.upkuajing/.env`; use a presence check instead, protect that file with owner-only permissions, and review any recharge-order or error-reporting action before approving it.
scripts/auth.py:69API Key File Is Created Without Explicit Owner-Only Permissions
requirements.txt:1Dependency Installation Is Not Reproducibly Pinned
The skill claims to analyze customs trade-partner data, but its documented behavior also includes API-key provisioning, account inspection, balance handling, recharge order creation, and pricing queries. This mismatch is security-relevant because users may authorize a data-analysis skill without realizing it can also manipulate credentials and trigger account-related workflows with financial consequences.
The skill claims to analyze customs trade-partner data, but its documented behavior also includes API-key provisioning, account inspection, balance handling, recharge order creation, and pricing queries. This mismatch is security-relevant because users may authorize a data-analysis skill without realizing it can also manipulate credentials and trigger account-related workflows with financial consequences.
The skill claims to analyze customs trade-partner data, but its documented behavior also includes API-key provisioning, account inspection, balance handling, recharge order creation, and pricing queries. This mismatch is security-relevant because users may authorize a data-analysis skill without realizing it can also manipulate credentials and trigger account-related workflows with financial consequences.
The skill explicitly instructs displaying the contents of ~/.upkuajing/.env with cat, which would expose the API key in plaintext to the agent and potentially to user-visible output, logs, or downstream tools. In this context the danger is elevated because the file is specifically described as storing the active credential used for billable API access.
Referencing and reading a .env file that contains UPKUAJING_API_KEY creates a direct credential-access path. If the agent follows this guidance, the secret can be exposed, reused for unauthorized API consumption, or leaked into transcripts and telemetry.
使用此技能需要API密钥。API密钥保存在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
The workflow tells the agent to check the local .env for the API key and supports automatically applying for and saving a new key to that file. This combines credential discovery with credential persistence, increasing the blast radius if the agent or logs are compromised and normalizing secret handling in an unsafe plaintext store.
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
The instruction to have users manually add keys to ~/.upkuajing/.env, or let the agent obtain and auto-save a new key there, encourages insecure secret lifecycle management. In a skill that also performs network and account actions, compromising that local file could enable unauthorized data access and billable operations.
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
### **账户充值**
The script includes account provisioning, balance lookup, and payment-order creation capabilities that are outside the stated purpose of analyzing customs trade-partner data. Scope expansion in a skill increases attack surface and can enable unintended financial or account-management actions if the skill is invoked in the wrong context.
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 script writes a newly issued API key into a plaintext .env file under the user's home directory. Plaintext secret storage is risky because other local users, backup systems, logs, or misconfigured permissions can expose the credential and allow unauthorized API use.
"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")
On failure, the script returns the path to the secret file location, which can disclose credential storage details to callers or logs. While not exposing the key itself, revealing the exact secret path can aid local attackers or increase the chance of accidental disclosure and mishandling.
except IOError as e:
return {
"success": False,
"message": f"API密钥申请成功,但保存到 .env 文件失败:{str(e)}。\n请手动设置环境变量 {API_KEY_ENV}。",
"envFilePath": str(env_file)
}
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 broad capabilities implied by its workflow—reading local files, writing credential files, using environment secrets, and making network requests—without an explicit tool scope or permission boundary. That makes it harder for a runtime or reviewer to constrain behavior and increases the chance that sensitive operations such as credential handling or outbound requests occur without clear isolation.
The document instructs agents to report exceptions by sending request parameters, response data, and error context to a remote API, but it does not require explicit user notice, consent, or strict minimization before transmission. Even though it states sensitive fields will be masked automatically, error context, raw request parameters, and response bodies can still contain confidential business data, identifiers, or model outputs that should not be forwarded by default.
The module description and all user-facing help/messages in this file are presented exclusively in Chinese. Under the policy, forcing a specific language without user opt-in or a documented region-specific justification 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:
Creating recharge orders and exposing pricing/account-adjacent actions are not necessary for the declared business purpose of partner analysis. In an agent ecosystem, unnecessary financial operations increase the risk of abuse, confusion, and unintended charges.
This code file contains natural-language content that assumes a Chinese-speaking user, beginning with the module docstring and continuing throughout user-facing strings. Under the policy, forcing a specific language without opt-in or a documented regional justification is a natural-language policy violation.
The module title, description, CLI description, help text, and error messages are written only in Chinese, which imposes a language choice without any opt-in or alternative locale. The policy requires flagging language or locale constraints when the skill forces a specific language without user choice or an explicit justified regional limitation.
This Python file contains natural-language descriptions, argument help text, and error messages exclusively in Chinese. That imposes a fixed language/locale on users with no documented choice or opt-in, which matches the stated policy-violation category for language constraints.
Detected: suspicious.exposed_secret_literal