T09 · Insecure Skill Coding Practices
- Location
SKILL.md:38- Finding
API Key Exposed Through Unsafe Display Guidance and Insufficient File Permission Enforcement
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly performs the stated colleague lookup, but it also handles API keys and billing-related account actions in ways users should review carefully before installing.
Review before installing. Use this only if you trust the Upkuajing service, understand that lookups can incur fees, and are comfortable with local plaintext API-key storage. Avoid printing the `.env` file, prefer an environment variable or secret manager, verify any recharge or payment URL before acting, and avoid sending raw request or response data in error reports.
SKILL.md:38API Key Exposed Through Unsafe Display Guidance and Insufficient File Permission Enforcement
requirements.txt:1Unbounded and Unverified Third-Party Dependency Installation
The skill includes remote version checks, local cache writes, and parsing of local metadata that are not part of the stated colleague lookup function. Hidden auxiliary behavior broadens attack surface and creates additional network and filesystem side effects that a user would not reasonably expect from a simple lookup skill.
The skill includes remote version checks, local cache writes, and parsing of local metadata that are not part of the stated colleague lookup function. Hidden auxiliary behavior broadens attack surface and creates additional network and filesystem side effects that a user would not reasonably expect from a simple lookup skill.
The skill includes remote version checks, local cache writes, and parsing of local metadata that are not part of the stated colleague lookup function. Hidden auxiliary behavior broadens attack surface and creates additional network and filesystem side effects that a user would not reasonably expect from a simple lookup skill.
The skill explicitly instructs reading the local file containing the API key from ~/.upkuajing/.env. In context, this is credential access to a secret store, and exposing or unnecessarily reading raw secret files can lead to leakage, reuse of credentials, and compromise of the linked account.
使用此技能需要API密钥。API密钥保存在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
The skill instructs checking for the API key in ~/.upkuajing/.env and, if absent, obtaining a new key and saving it automatically to the same local secret file. This combines credential discovery, issuance, and persistent storage in one workflow, increasing the risk of unauthorized credential creation or unsafe secret handling on the host.
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
The skill continues the same secret-handling pattern by directing the agent to interact with and write to ~/.upkuajing/.env for API key storage. In a low-trust skill context, instructions to access and persist credentials locally are especially dangerous because they normalize secret exposure and expand the blast radius if the agent or host is compromised.
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
### **账户充值**
The file implements API key provisioning, account inspection, and payment-order creation, which materially exceeds the declared skill purpose of colleague/internal-team lookup. This capability mismatch is dangerous because users or orchestrators may grant trust based on the published description while the skill also performs account-management operations against an external service.
The script manages API credentials via a local .env file and later writes secrets there, which creates credential exposure risk if the file permissions are weak, the path is user-accessible, or the file is accidentally logged/committed. In this skill context, the code is directly provisioning a live API key, so mishandling storage can immediately enable unauthorized API use and account abuse.
"""
申请新的 API 密钥。
"""
# 检查是否已存在 .env 文件和 API key
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
Reading an existing .env file to inspect stored API keys is part of credential handling and expands the secret exposure surface, especially because parsing is done in plaintext. Any compromise of the local environment or accidental inclusion of the file can reveal the active key and enable unauthorized requests.
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 the newly issued API key directly to a .env file in plaintext, creating a durable credential that may be exposed through backup systems, misconfigured permissions, or accidental source-control inclusion. Because this key grants access to the external platform account, compromise can lead to unauthorized consumption, billing, and data access under the victim account.
"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'
# 日志开关
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env_file() -> Dict[str, str]:
"""
从 ~/.upkuajing/.env 文件加载环境变量。
Returns:
环境变量字典
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env_file() -> Dict[str, str]:
"""
从 ~/.upkuajing/.env 文件加载环境变量。
Returns:
环境变量字典
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env_file() -> Dict[str, str]:
"""
从 ~/.upkuajing/.env 文件加载环境变量。
Returns:
环境变量字典
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env_file() -> Dict[str, str]:
"""
从 ~/.upkuajing/.env 文件加载环境变量。
Returns:
环境变量字典
The skill declares capabilities that involve environment access, local file reads/writes, and network use, but it does not define any explicit tool scope or permissions boundary. That increases the chance an agent may exercise broader-than-expected powers, including reading secrets or writing files, without clear user-facing constraint.
The documentation directs the agent to handle account registration, API key issuance, recharge-order creation, and payment flow for a skill whose stated purpose is colleague lookup. In context, these features materially expand the operational scope into credential lifecycle and financial actions, increasing the chance of unauthorized or socially engineered account operations.
The API reference explicitly encourages sending raw request parameters, response data, and exception context for error reporting, while only stating that sensitive fields will be 'automatically masked' and giving no concrete guidance on what must never be uploaded. In practice, stack traces, request payloads, and response bodies often contain personal data, credentials, internal identifiers, or proprietary business information, so this can lead to unintended data disclosure to the platform-side logging system.
The top-level docstring states the script is for authentication management, API key issuance, and recharge, which conflicts with the advertised networking/research purpose of the skill. This discrepancy is a supply-chain trust problem because reviewers and users may underestimate what the skill can do based on the external description.
This code file contains natural-language text exclusively in Chinese in the module docstring and CLI/help output, which effectively imposes a specific language on users. The policy allows locale constraints only when the skill offers opt-in choice or clearly documents a justified region-specific limitation, neither of which is present here.
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 account balance/pricing are monetization and account-management features unrelated to the narrow user-facing claim of enterprise colleague lookup. In a skill ecosystem, undisclosed billing capabilities increase the risk of deceptive behavior, unexpected charges, or misuse of trusted execution context.
This code file contains natural-language instructions and documentation such as the module docstring and operational comments exclusively in Chinese. Under the policy, forcing a specific language without offering a user choice or documenting a justified locale constraint is a language/locale policy violation.
该技能的对外目的描述是查找企业内同事与团队成员,并未说明会访问宿主环境中的环境变量或用户主目录下的 ~/.upkuajing/.env 凭据文件。虽然访问远程企业资料库需要认证本身是合理实现细节,但从开发者意图审计角度看,主动读取宿主凭据存储属于额外敏感能力,描述中没有体现。
Detected: suspicious.exposed_secret_literal