T09 · Insecure Skill Coding Practices
- Location
SKILL.md:37- Finding
API Key Exposed by Documented Plaintext File Inspection
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its company-search purpose, but it needs review because it handles paid API access and local API keys in ways that could expose secrets or affect an account balance.
Review this skill before installing if the account has real balance or sensitive leads. Do not print or paste the contents of ~/.upkuajing/.env, restrict that file to the account owner, confirm every paid query or top-up action before running it, and avoid sending diagnostic reports that include customer data, prompts, credentials, or full API responses.
SKILL.md:37API Key Exposed by Documented Plaintext File Inspection
scripts/auth.py:62API Key File Is Created Without Explicit Restrictive Permissions
requirements.txt:1Unbounded Dependency Version Prevents Reproducible and Reviewed Installation
The finding indicates the skill may perform version/update checks, local cache or metadata access, and network requests unrelated to company search. If accurate, these side behaviors expand the attack surface and further weaken user understanding of what a business-lookup skill actually does.
The finding indicates the skill may perform version/update checks, local cache or metadata access, and network requests unrelated to company search. If accurate, these side behaviors expand the attack surface and further weaken user understanding of what a business-lookup skill actually does.
The finding indicates the skill may perform version/update checks, local cache or metadata access, and network requests unrelated to company search. If accurate, these side behaviors expand the attack surface and further weaken user understanding of what a business-lookup skill actually does.
The skill explicitly instructs reading ~/.upkuajing/.env and even suggests cat on the file that stores the API key. That normalizes direct access to secrets and risks accidental disclosure of credentials into logs, transcripts, terminal history, or model context, especially dangerous in a skill whose main purpose is only company search.
This skill requires an API key. The API key is stored in the ~/.upkuajing/.env file:
cat ~/.upkuajing/.env
Example file content:
The workflow tells the agent to check the .env file for UPKUAJING_API_KEY and supports automatically creating and saving new credentials there. This combines credential discovery, creation, and local persistence in a way that exceeds the expected scope of a lookup skill and increases the chance of secret leakage or unauthorized account linkage.
### **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 continue the same credential-access pattern by directing inspection of the local .env file and automatic key persistence. In context, this is more dangerous because the skill also supports paid operations and account actions, so compromise of the API key can lead to both data access and financial abuse.
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**
The file implements authentication, account-info, pricing, and recharge-order functionality, which exceeds the stated purpose of a company-search/firmographic enrichment skill. This scope expansion is dangerous because it introduces billing and account-management capabilities that could trigger financial actions or expose account metadata in environments where users only expect lookup behavior.
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():
This line persists a newly issued API key into a .env file on disk, creating credential exposure risk if permissions are weak or the file is later copied, logged, or committed. Although not credential theft in itself, it materially increases the chance of secret compromise.
"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")
The new_rec_order function creates recharge/payment orders, which is unrelated to company lookup and could be abused to initiate unwanted billing flows. In the context of a lead-generation/company-search skill, hidden payment functionality is especially risky because users and integrators would not reasonably expect financial side effects.
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 capabilities that imply reading environment variables, accessing local files, writing credential material, and making network requests, but it does not declare a restrictive tool scope such as explicit permissions or allowed tools. That creates an unnecessary trust gap: a user invoking a company-search skill may not realize it can also touch local credential files and perform unrelated outbound actions.
The trigger phrases are broad enough to activate on common research or sourcing requests, which can cause the skill to run in contexts broader than users intended. Because the skill can incur fees and interact with credentials and external services, overbroad activation increases the chance of unintended data exposure or paid API usage.
The markdown states that industry and product names must be in English, which imposes a language constraint on user input. The file does not present this as an optional preference or explain a policy/compliance reason for requiring English-only input.
This line states that industry names must be in English, which is a natural-language locale restriction. Because the file does not frame this as an API limitation with user-facing accommodation or an explicitly justified regional requirement, it conflicts with the language/locale policy criteria.
The documentation explicitly exposes filtering and retrieval capabilities for employee and person contact data, including phone, email, WhatsApp, and core member contact existence, plus a field showing an employee contact. In a lead-generation and supplier-sourcing skill, this materially increases the risk of privacy-invasive use, scraping, or targeted outreach without any warning, access control guidance, or lawful-use constraints.
The documentation instructs agents to send request parameters, response payloads, and exception context to an external error-reporting endpoint. Even if the platform claims sensitive fields are auto-masked, this still creates a privacy and data-handling risk because request/response bodies and stack traces commonly contain personal data, credentials, business-sensitive content, or user prompts, and the doc does not require user notice, minimization, or explicit consent.
The module description, CLI help text, and user-facing messages are all in Chinese, with no mechanism to choose another language or document that the skill is intentionally locale-specific. Under the policy, hard-forcing a language without opt-in is a natural-language policy violation.
The script can provision and persist API keys as a standalone capability, which is broader than the user-facing purpose of company search. While API key issuance may support backend access, bundling it directly into the skill increases the attack surface and can normalize credential handling in a context where users may not expect secret creation and storage.
The explicit require_auth=False setting indicates an unsafe default for a sensitive operation that provisions API credentials. If exposed through an agent or automation pipeline, this can facilitate unauthorized account creation or uncontrolled issuance unless compensated by robust server-side protections.
pass # 如果读取失败,继续执行
# 不需要认证申请新密钥
response = make_request('/agent/auth/create', {}, require_auth=False)
# 检查是否申请成功
if response.get('code') != 0:
Detected: suspicious.exposed_secret_literal