T05 · Unauthorized Access and Privilege Escalation
- Location
SKILL.md:40- Finding
Unnecessary Disclosure of the Credential File
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does what it says, but it asks the agent to expose a local API-key file and persists credentials without strong safeguards.
Review before installing. This skill uses a paid third-party UpKuaJing API, sends LinkedIn-related identifiers to that service, can create payment/top-up flows, and stores an API key under your home directory. Do not let an agent print `~/.upkuajing/.env`; prefer setting only `UPKUAJING_API_KEY` through a scoped secret mechanism, and confirm every paid or error-reporting action explicitly.
SKILL.md:40Unnecessary Disclosure of the Credential File
scripts/auth.py:71API Key Stored Without Explicit Owner-Only File Permissions
requirements.txt:1Unbounded Third-Party Dependency Version
Remote version checks and local cache writes in the user's home directory are ancillary behaviors not evident from the declared alumni-search purpose. These extra capabilities expand the attack surface by enabling persistent local state changes and unsolicited outbound requests that users may not expect from a simple lookup tool.
Remote version checks and local cache writes in the user's home directory are ancillary behaviors not evident from the declared alumni-search purpose. These extra capabilities expand the attack surface by enabling persistent local state changes and unsolicited outbound requests that users may not expect from a simple lookup tool.
Remote version checks and local cache writes in the user's home directory are ancillary behaviors not evident from the declared alumni-search purpose. These extra capabilities expand the attack surface by enabling persistent local state changes and unsolicited outbound requests that users may not expect from a simple lookup tool.
Remote version checks and local cache writes in the user's home directory are ancillary behaviors not evident from the declared alumni-search purpose. These extra capabilities expand the attack surface by enabling persistent local state changes and unsolicited outbound requests that users may not expect from a simple lookup tool.
The skill explicitly instructs reading ~/.upkuajing/.env, which is a credential store containing API secrets. Directing an agent to access local secret files is dangerous because it can expose tokens beyond least-privilege needs, and the file may contain additional sensitive values beyond the single API key referenced.
This skill requires an API key. The API key is stored in the ~/.upkuajing/.env file:
cat ~/.upkuajing/.env
Example file content:
The workflow asks the agent to check the local .env file for a key and potentially guide manual insertion of credentials into that file. This creates unnecessary credential handling by the agent and increases the chance of secret disclosure, mishandling, or persistence in an insecure location.
### **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;
Automatically applying for a new key and saving it to ~/.upkuajing/.env combines credential creation with local persistence in a general-purpose secret file. This is risky because it normalizes automatic secret generation/storage by the skill and may leave long-lived credentials on disk without adequate user review, rotation, or access controls.
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 account provisioning, balance lookup, pricing, and recharge flows for a third-party platform, which does not align with the declared LinkedIn alumni discovery purpose. This kind of scope mismatch is dangerous because it can conceal unexpected credential, billing, and external-service interactions behind an unrelated skill description, 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():
Writing a newly created API key directly into a .env file on disk stores a sensitive credential in plaintext, which can be exposed through weak file permissions, backups, logs, or accidental inclusion in tooling. In a mismatched skill context, this is more concerning because users may not realize the skill is provisioning and persisting third-party credentials at all.
"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")
Creating recharge orders and exposing pricing/account management inside an alumni discovery skill introduces payment-related capability that is unrelated to the advertised function. Hidden monetization or billing actions in a mismatched context increase the risk of unauthorized charges, deceptive behavior, and users triggering financial workflows they did not expect.
The code is wired to a generic third-party Upkuajing API service rather than a narrowly scoped LinkedIn alumni capability, which indicates scope expansion beyond the declared skill purpose. In an agent skill, this mismatch is dangerous because it can route user data to an unrelated external service and enable undisclosed data processing outside the expected trust boundary.
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 alumni connections using school and personnel identifiers, but this code only validates error-report parameters and sends them to an '/agent/skill/error/report' endpoint. That behavior is operational telemetry for the hosting platform, not part of alumni research, talent sourcing, or B2B contact enrichment.
The skill declares access patterns that involve environment variables, filesystem reads/writes, and network operations, but it does not declare an explicit tool scope or permission boundary. That makes the real capability surface opaque to users and reviewers, increasing the chance that credential access, local file modification, or external requests occur without clear authorization expectations.
The documentation instructs the agent to perform API-key provisioning, account top-up, price lookups, and error-report submission in addition to alumni discovery. These capabilities materially expand the financial, privacy, and account-management risk of the skill, especially because users may invoke it expecting only a search function.
The API explicitly supports sending request parameters, response payloads, and exception context to a centralized error-report endpoint. Even though it states sensitive fields will be automatically masked, there is no explicit guidance to minimize data collection, avoid secrets/PII in context strings, or obtain user/operator awareness before transmitting potentially sensitive debugging data, creating a real privacy and data-leakage risk through logs and telemetry.
The code silently performs a network request to create a new API key and then stores that credential locally, without an explicit warning about transmitting data to a remote service and writing secrets to disk. Even if intended, this is risky because users may not understand they are provisioning credentials for a third-party service or where those credentials will persist.
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:
Detected: suspicious.exposed_secret_literal