T09 · Insecure Skill Coding Practices
- Location
SKILL.md:39- Finding
Credential File Contents Exposed Through Unsafe Setup Instructions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill performs the advertised LinkedIn colleague lookup, but it also handles paid-account credentials, top-up orders, and telemetry in ways users should review before installing.
Review this before installing if you are comfortable using a paid UpKuaJing API for LinkedIn colleague data. Avoid printing or sharing ~/.upkuajing/.env, prefer setting the API key through a safer secret mechanism, confirm every paid query or top-up action explicitly, and consider the privacy/legal basis for sales outreach or contact expansion.
SKILL.md:39Credential File Contents Exposed Through Unsafe Setup Instructions
scripts/auth.py:68API Key File Is Written Without Enforced Restrictive Permissions
requirements.txt:1Unbounded Dependency Version Allows Unreviewed Future Releases
scripts/common.py:194Automatic Version Check Sends Undisclosed Usage Metadata
The declared purpose is narrowly framed as LinkedIn colleague lookup, but the documentation also instructs the agent to create API keys, manage account state, retrieve pricing, create top-up orders, and store credentials locally. This mismatch is dangerous because users may authorize a simple lookup skill without realizing it can perform account-management and billing-adjacent actions with broader security and financial implications.
The declared purpose is narrowly framed as LinkedIn colleague lookup, but the documentation also instructs the agent to create API keys, manage account state, retrieve pricing, create top-up orders, and store credentials locally. This mismatch is dangerous because users may authorize a simple lookup skill without realizing it can perform account-management and billing-adjacent actions with broader security and financial implications.
The declared purpose is narrowly framed as LinkedIn colleague lookup, but the documentation also instructs the agent to create API keys, manage account state, retrieve pricing, create top-up orders, and store credentials locally. This mismatch is dangerous because users may authorize a simple lookup skill without realizing it can perform account-management and billing-adjacent actions with broader security and financial implications.
The declared purpose is narrowly framed as LinkedIn colleague lookup, but the documentation also instructs the agent to create API keys, manage account state, retrieve pricing, create top-up orders, and store credentials locally. This mismatch is dangerous because users may authorize a simple lookup skill without realizing it can perform account-management and billing-adjacent actions with broader security and financial implications.
The skill explicitly supports sales outreach and contact expansion using colleague and organizational data, creating a significant privacy and misuse risk. In context, this is more dangerous because the skill is designed to operationalize personal/professional relationship data for prospecting rather than a narrowly necessary business function.
The documentation instructs reading the entire ~/.upkuajing/.env file with cat to obtain an API key. That exposes secrets unnecessarily and may reveal additional credentials stored in the same file, enabling account compromise or misuse of paid API access.
This skill requires an API key. The API key is stored in the ~/.upkuajing/.env file:
cat ~/.upkuajing/.env
Example file content:
The skill tells the agent to have users manually add API keys to a local .env file and to auto-save newly created keys there. Storing and manipulating long-lived credentials in plaintext local files raises theft and persistence risks, particularly in multi-tool or shared environments.
### **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 repeated instruction to inspect ~/.upkuajing/.env for credential presence encourages broad file access to secret material instead of a minimal existence check. In this skill context, that is especially dangerous because the same workflow also includes networked account and billing actions, so stolen credentials can immediately be abused.
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 API-key issuance, account lookup, recharge, and pricing functions for a third-party platform, which does not align with the declared LinkedIn colleague discovery purpose. Capability mismatch is dangerous because it can conceal undeclared data flows, billing behavior, or external service dependence under an unrelated skill label, reducing informed user consent and review effectiveness.
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 reads the local .env file and, if an API key exists, includes the first 10 characters of that secret in a returned message. Even partial secret disclosure increases credential exposure risk through logs, terminal history, screenshots, or higher-level wrappers that capture stdout/stderr.
env_file = UPKUAJING_ENV_FILE
if env_file.exists():
# 读取现有的 .env 文件
try:
with open(env_file, 'r', encoding='utf-8') as f:
content = f.read()
Recharge-order creation and pricing retrieval are monetization/account-management features unrelated to LinkedIn colleague lookup. In this context, they create hidden financial interaction surfaces that could trigger unexpected charges, obscure third-party dependencies, or facilitate abuse through a misleadingly labeled skill.
The utility module is wired to an unrelated third-party API (openapi.upkuajing.com) and generic persistence features rather than the manifest’s stated LinkedIn colleague-lookup behavior. This mismatch is dangerous because it indicates scope drift or repurposed code that can transmit user-supplied data to an undisclosed external service, undermining user expectations and creating data exfiltration/privacy risk in a skill intended for LinkedIn/account-intelligence workflows.
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 manifest describes a skill for finding LinkedIn colleagues, mapping organizational structures, and gathering B2B contacts. This file instead collects runtime metadata and context and sends an exception report to a platform endpoint, which is operational telemetry behavior rather than colleague lookup or account intelligence functionality.
The skill declares no explicit tool restrictions while its documented behavior requires reading environment secrets, accessing local files, writing to user storage, and making network calls. In an agent environment, missing scope boundaries increases the chance the skill can access more data or capabilities than users expect, especially because it handles credentials and paid external operations.
The trigger phrases are broad enough to activate on generic research or account-intelligence requests, which can cause the agent to invoke a credentialed, fee-incurring external lookup more often than intended. Overbroad triggering is especially risky here because the skill can access personal colleague data and initiate paid API operations.
The skill documentation includes credential acquisition, local secret storage, account information retrieval, and payment/top-up flows that go beyond a simple colleague search. Expanding the operational surface in one skill increases risk of unauthorized billing actions, unsafe secret handling, and user confusion about what the agent may do.
This API reference explicitly documents retrieval of a person's colleague information for account intelligence and outreach, but provides no privacy notice, lawful-use constraints, access-control expectations, or handling requirements for personal data. In the context of a skill designed for internal team discovery and contact expansion, that omission increases the risk of misuse for unauthorized profiling, social graph mapping, and privacy-invasive sales targeting.
The API documentation explicitly allows reporting raw request parameters, response data, and exception context, which commonly contain secrets, personal data, internal identifiers, or stack traces. Even though it says sensitive fields will be automatically redacted, it does not define the redaction scope or instruct callers to minimize what they send, creating a realistic risk of privacy leakage and exposure of internal system details through telemetry.
Detected: suspicious.exposed_secret_literal