T09 · Insecure Skill Coding Practices
- Location
scripts/auth.py:79- Finding
API Key File Created Without Restrictive Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly supports the advertised education-history lookup, but it bundles sensitive credential, billing, telemetry, and hidden update-check behavior that users should review before installing.
Install only if you trust Upkuajing with the queried person/profile data and your API account. Do not print or paste the contents of ~/.upkuajing/.env into chat or logs, review file permissions after key creation, use a virtual environment for dependencies, and require explicit confirmation before any paid query, recharge-order creation, or diagnostic error report.
scripts/auth.py:79API Key File Created Without Restrictive Permissions
SKILL.md:36Documentation Encourages Printing the API Key to Standard Output
requirements.txt:1Unpinned Third-Party Dependency Allows Unreviewed Future Versions
If the broader skill package performs update checks, parses local metadata, or writes version cache files while claiming to perform person-education lookups, that is another material description mismatch. Hidden update and local-state behaviors are risky because they add undeclared network egress and file-system modification channels unrelated to the user’s expected task.
If the broader skill package performs update checks, parses local metadata, or writes version cache files while claiming to perform person-education lookups, that is another material description mismatch. Hidden update and local-state behaviors are risky because they add undeclared network egress and file-system modification channels unrelated to the user’s expected task.
If the broader skill package performs update checks, parses local metadata, or writes version cache files while claiming to perform person-education lookups, that is another material description mismatch. Hidden update and local-state behaviors are risky because they add undeclared network egress and file-system modification channels unrelated to the user’s expected task.
If the broader skill package performs update checks, parses local metadata, or writes version cache files while claiming to perform person-education lookups, that is another material description mismatch. Hidden update and local-state behaviors are risky because they add undeclared network egress and file-system modification channels unrelated to the user’s expected task.
The skill instructs reading ~/.upkuajing/.env directly and even shows cat ~/.upkuajing/.env, which exposes the location and retrieval method for secrets. In an agent setting, encouraging direct credential-file reads increases the risk of secret disclosure in logs, outputs, or downstream tool calls, especially since the skill’s main purpose does not require revealing the key contents to the user.
使用此技能需要API密钥。API密钥保存在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
This section directs the agent to inspect a local secret file for UPKUAJING_API_KEY and, if absent, to initiate key application and save the new key into the same file. That combines secret discovery, account provisioning, and persistent secret storage inside a low-trust skill flow, increasing the chance of credential exposure, unauthorized account creation, or insecure storage practices.
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
Automatically saving a newly issued API key to ~/.upkuajing/.env establishes persistent local credential handling without any documented safeguards such as file-permission checks, encryption, or redaction. In the context of a skill expected to perform education lookups, this is disproportionately dangerous because it expands the trust boundary from data retrieval into secret lifecycle management.
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
### **账户充值**
The file implements API key issuance, account inspection, pricing, and recharge operations, while the skill metadata describes only personnel education/background lookup. This scope mismatch is dangerous because it introduces hidden financial and credential-management capabilities that users and reviewers would not reasonably expect from the advertised skill, increasing the risk of misuse or deceptive bundling.
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 the newly issued API key in plaintext to a .env file under the user's home directory. Plaintext secret storage increases the risk of credential disclosure through local compromise, backups, misconfigured permissions, or accidental inclusion in logs or support bundles.
"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")
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'
# 日志开关
This script adds a remote error-reporting capability that is unrelated to the skill’s declared purpose of querying personnel education/background data, which increases the attack surface and creates an undisclosed telemetry channel. Because the reported payload includes fields like requestPath and context and is sent off-box via make_request, operational or user-derived data may be exfiltrated to the platform without necessity for the advertised function.
The skill declares capabilities that imply environment access, local file access, file writes, and network use, but it does not define any explicit tool scope or permission boundaries. In an agent environment, that creates overbroad authority and makes it easier for the skill to read credentials, modify local state, or invoke remote services beyond the narrowly expected education-query use case.
文件从名称后缀“zh”到标题与说明内容均默认中文,但未说明这是面向中文用户的受限场景,也未给出用户可选择其他语言的机制。根据语言/地区政策,强制特定语言而无用户选择属于自然语言策略风险。
L003 用自然语言概述了可“查询目标人员的履历与学术背景”“完善 B2B 销售客户画像”等用途,但没有给出明确触发短语、调用边界或不应触发的负例。对 markdown 技能说明而言,这种宽泛描述可能与常见用户请求重叠,增加误调用风险。
The documentation embeds account management, API key issuance,充值 ordering, pricing lookup, and exception reporting into a skill framed as an education-history query tool. This expands the operational scope into credential handling and billing workflows, making accidental misuse or social engineering easier because sensitive actions are bundled with a routine data-retrieval task.
The documentation explicitly instructs callers to send raw request parameters, response data, and exception context to an error-reporting endpoint. Even if the platform says sensitive fields are automatically redacted, the skill handles personal profile and education data, so these payloads may still contain personal data, identifiers, or contextual secrets that are unnecessary for centralized error reporting. The absence of a clear minimization rule, user warning, or explicit field allowlist creates a real privacy and data-exposure risk.
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:
Recharge-order creation and balance-management capabilities exceed the minimum permissions and actions needed for an education/background lookup skill. In context, this expands the blast radius from data retrieval to billable account actions, enabling unexpected charges or abuse if the script is invoked by a user or higher-level agent without understanding these side effects.
Detected: suspicious.exposed_secret_literal