T09 · Insecure Skill Coding Practices
- Location
SKILL.md:66- Finding
API Key May Be Exposed Through Documented Plaintext Inspection
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is coherent but should be reviewed carefully because it can retrieve personal contact data, incur paid API usage, and stores API keys in a plaintext local file.
Install only if you are comfortable using a paid third-party B2B data service that may return personal professional contact details. Use a secret manager or environment variable instead of printing or pasting the API key, restrict ~/.upkuajing/.env permissions if you use it, confirm costs before bulk searches or enrichment, and avoid sending raw contact data or sensitive query results in error reports.
SKILL.md:66API Key May Be Exposed Through Documented Plaintext Inspection
scripts/auth.py:60API Key File Is Created Without Enforced Owner-Only Permissions
requirements.txt:1Dependency Specification Allows Unreviewed Future Releases
The skill includes telemetry/error reporting that submits request metadata and execution context to the platform, but this behavior is not clearly foregrounded in the primary description. Hidden or under-disclosed outbound reporting can leak business queries, identifiers, or operational metadata, especially in a lead-generation context involving personal contact data.
The skill includes telemetry/error reporting that submits request metadata and execution context to the platform, but this behavior is not clearly foregrounded in the primary description. Hidden or under-disclosed outbound reporting can leak business queries, identifiers, or operational metadata, especially in a lead-generation context involving personal contact data.
The skill includes telemetry/error reporting that submits request metadata and execution context to the platform, but this behavior is not clearly foregrounded in the primary description. Hidden or under-disclosed outbound reporting can leak business queries, identifiers, or operational metadata, especially in a lead-generation context involving personal contact data.
The skill includes telemetry/error reporting that submits request metadata and execution context to the platform, but this behavior is not clearly foregrounded in the primary description. Hidden or under-disclosed outbound reporting can leak business queries, identifiers, or operational metadata, especially in a lead-generation context involving personal contact data.
The skill includes telemetry/error reporting that submits request metadata and execution context to the platform, but this behavior is not clearly foregrounded in the primary description. Hidden or under-disclosed outbound reporting can leak business queries, identifiers, or operational metadata, especially in a lead-generation context involving personal contact data.
The skill instructs reading a local .env file that stores the API key, including an explicit command to display its contents. In an agent environment, this is credential exposure behavior: it can reveal secrets to the model, logs, transcripts, or downstream tooling beyond the minimum needed for authentication.
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 for the API key in a local .env file and potentially handle user-supplied credentials for manual storage. This expands secret-handling surface area and risks accidental disclosure, insecure persistence, or logging of credentials in a conversational workflow.
### **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 skill not only reads secret state from .env but also auto-saves newly created API keys to a local file. Automatic persistence of freshly issued credentials increases the chance of compromise through file exposure, weak filesystem permissions, backups, or later accidental disclosure by the agent.
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**
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 directly into a .env file in plaintext without setting restrictive permissions. On multi-user systems or in environments where home-directory files are backed up, synced, or broadly readable, this can expose the credential and allow unauthorized use of the service API.
"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 error path encourages manual setting of the API key and returns the environment file path, reinforcing a workflow centered on plaintext secret handling. In the context of a lead-generation skill that accesses verified business contacts, compromise of the API key could enable unauthorized data retrieval or account misuse.
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 capabilities that include environment access, local file reads/writes, and network use, but it does not define any explicit tool scope or permission boundary. In an agent setting, this weakens containment and makes it harder to enforce least privilege, especially because the skill handles API keys, writes local state, and can contact remote services.
The trigger phrases are broad enough to activate on common requests such as finding people, contacts, or companies, which increases the chance that the skill runs in contexts where users did not intend lead-generation, contact discovery, or fee-incurring actions. In a skill that can retrieve personal contact details and initiate paid API calls, overbroad activation materially raises misuse risk.
The skill advertises retrieval of verified personal contact details, including emails, phone numbers, and WhatsApp profiles, without a prominent privacy or acceptable-use warning. In this context, the omission increases the risk of privacy-invasive enrichment, unsolicited outreach, and collection of personal data without clear user awareness or policy gating.
The note states that product names and industry names must be in English, which is a language constraint expressed as a mandatory rule. This forces a specific language/locale behavior without offering user choice or explaining a justified regional/compliance need.
The documentation explicitly exposes access to employee contact data via fields like person_contact_show without any privacy warning, consent constraints, or permissible-use guidance. In the context of a lead-generation skill that advertises verified emails, phone numbers, and WhatsApp profiles, this materially increases the risk of privacy abuse, targeted phishing, spam, and unlawful processing of personal data.
The API supports filtering people by gender, a sensitive/protected attribute in many contexts, without any warning, purpose limitation, or anti-discrimination guardrails. In a people-search and lead-generation workflow, this can enable discriminatory targeting or exclusion and create regulatory and reputational risk.
The API reference explicitly supports discovery of personal contact channels such as email, phone, and WhatsApp for professional contacts, but provides no privacy, consent, lawful-basis, or acceptable-use constraints. In the context of a lead-generation skill, this materially increases the risk of bulk harvesting, unsolicited outreach, and misuse of personal data across jurisdictions.
The document instructs agents to send request parameters, response payloads, and error context to a platform error-reporting API, but it does not require explicit user notice, consent, or strict minimization before transmission. In a skill focused on company/contact search and verified emails/phone numbers, these fields can easily contain personal data, business-sensitive queries, API outputs, or stack traces, creating a meaningful privacy and data-sharing risk if reported automatically.
This code file contains user-facing natural language that is exclusively Chinese in the module docstring, and the CLI also presents Chinese-only descriptions/help text. Per the policy, forcing a specific language without offering a choice or documenting a justified locale constraint is a natural-language policy violation.