T09 · Insecure Skill Coding Practices
- Location
scripts/auth.py:73- Finding
API Key Exposure Through Documentation and Insecure Local File Creation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This paid trade-data skill mostly does what it says, but it handles API credentials and billing-related actions in ways users should review carefully before installing.
Install only if you are comfortable giving this skill access to a paid Upkuajing API account. Do not run the documented cat command on the .env file in an agent session, because it can expose the API key. Review the recharge/account commands before use, confirm any paid query separately, and consider storing the key with stricter local permissions or a secret manager.
scripts/auth.py:73API Key Exposure Through Documentation and Insecure Local File Creation
requirements.txt:1Unbounded Third-Party Dependency Version
Version checking, cache/metadata access, outbound requests to a version endpoint, and upgrade notices are outside the narrow scope of the stated analytics function. These hidden auxiliary behaviors increase network and filesystem exposure and can create unanticipated data leakage or supply-chain style risks if users believe the skill only performs local parameterized analysis queries.
Version checking, cache/metadata access, outbound requests to a version endpoint, and upgrade notices are outside the narrow scope of the stated analytics function. These hidden auxiliary behaviors increase network and filesystem exposure and can create unanticipated data leakage or supply-chain style risks if users believe the skill only performs local parameterized analysis queries.
Version checking, cache/metadata access, outbound requests to a version endpoint, and upgrade notices are outside the narrow scope of the stated analytics function. These hidden auxiliary behaviors increase network and filesystem exposure and can create unanticipated data leakage or supply-chain style risks if users believe the skill only performs local parameterized analysis queries.
Version checking, cache/metadata access, outbound requests to a version endpoint, and upgrade notices are outside the narrow scope of the stated analytics function. These hidden auxiliary behaviors increase network and filesystem exposure and can create unanticipated data leakage or supply-chain style risks if users believe the skill only performs local parameterized analysis queries.
The skill explicitly instructs reading the local file containing API credentials using a shell command. Direct access to ~/.upkuajing/.env exposes secrets unnecessarily and increases the risk that the agent, logs, or user-facing output could reveal the API key.
本技能需要API密钥。API密钥存储在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
The workflow directs checking for a secret in a local .env file and describes paths for providing or automatically storing the API key there. This normalizes agent interaction with credential files and risks exposing, overwriting, or mishandling secrets in a context where the skill is supposed to perform analytics, not credential management.
### **API密钥未设置**
首先检查 `~/.upkuajing/.env` 文件中是否有 UPKUAJING_API_KEY;
如果未设置,请让用户选择:
1. 用户已有密钥:用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有密钥:通过界面申请(`auth.py --new_key`),新密钥会自动保存到 ~/.upkuajing/.env
等待用户选择;
Automatically saving newly issued API keys into ~/.upkuajing/.env and instructing manual edits creates persistent local secret handling in a skill that also performs network actions. In the absence of strict permission boundaries, this increases the chance of credential theft, accidental disclosure, or cross-skill abuse of stored secrets.
首先检查 `~/.upkuajing/.env` 文件中是否有 UPKUAJING_API_KEY;
如果未设置,请让用户选择:
1. 用户已有密钥:用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有密钥:通过界面申请(`auth.py --new_key`),新密钥会自动保存到 ~/.upkuajing/.env
等待用户选择;
### **账户充值**
The script exposes authentication lifecycle and billing operations in a skill advertised only for regional trade-distribution queries. This mismatch expands the skill's effective privilege and attack surface, enabling key issuance, account inspection, and payment initiation that a user would not reasonably expect from the declared functionality.
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():
Reading an existing .env file to inspect API key contents means the skill handles local credentials directly. In the context of a data-analysis skill, this is overbroad secret access and increases the risk of credential disclosure, misuse, or accidental propagation in logs and outputs.
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
# 读取现有的 .env 文件
try:
with open(env_file, 'r', encoding='utf-8') as f:
content = f.read()
Writing a freshly issued API key into a plain-text .env file stores sensitive credentials in a location commonly readable by local tools, backups, and accidental uploads. This makes credential compromise much more likely, especially because the skill context does not justify local secret persistence as part of a regional-analysis feature.
"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")
Returning the environment file path in error output reveals where credentials are or will be stored, aiding local discovery of secrets by other components or users. This is not as severe as exposing the key itself, but it increases the exploitability of the insecure storage design.
except IOError as e:
return {
"success": False,
"message": f"API密钥申请成功,但保存到 .env 文件失败:{str(e)}。\n请手动设置环境变量 {API_KEY_ENV}。",
"envFilePath": str(env_file)
}
Creating recharge/payment orders is unrelated to HS-code regional analysis and introduces a financial-operation capability into a data-query skill. If triggered unexpectedly or chained by an agent, it could initiate unwanted purchase flows or social-engineer users into funding an account.
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 involving environment access, filesystem access, and network activity without an explicit tool-scope or permission boundary. That creates unnecessary privilege ambiguity: a caller may invoke what appears to be a narrow trade-analysis skill, while the implementation can also read local secrets, write files, and make outbound requests.
The manifest description lists trigger phrases such as “各国贸易” and “区域分析,” which are relatively broad and could overlap with many general commerce or analytics requests rather than uniquely indicating this area-distribution skill. The file does not provide exclusion conditions or narrower activation constraints to distinguish when this skill should activate versus related customs-analysis skills.
The documentation explicitly allows sending requestParams, responseData, and exception context to a remote error-reporting endpoint, but it does not clearly warn users that these fields may contain sensitive business data, identifiers, or stack traces leaving the local execution environment. In a skill-handling context, failures often occur precisely when unexpected data is present, which increases the chance that confidential inputs or internal system details are included in telemetry and exposed beyond the original trust boundary.
The module docstring and all user-facing CLI descriptions are written only in Chinese, which imposes a specific language on users without offering any language selection or opt-in. The policy explicitly calls out language or locale constraints as violations when no user choice is provided.
The code can request a new API key and persist it locally, which is a sensitive credential-management capability not proportional to the stated purpose of geographic trade analysis. Embedding credential provisioning in a broadly triggered skill increases the chance of silent key creation, mishandling, or later misuse by other local processes.
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 balance and pricing queries are outside the narrow business purpose of regional-distribution analysis and reveal operational and financial metadata. While less severe than key issuance or payment creation, this unnecessary capability broadens what the skill can enumerate about the user's account and platform usage.
Detected: suspicious.exposed_secret_literal