T09 · Insecure Skill Coding Practices
- Location
scripts/auth.py:60- Finding
API Key May Be Exposed Through Terminal Output and Permissive File Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This looks like a real paid company-and-people search skill, but it needs Review because it handles API keys and personal contact data with weak local storage and disclosure safeguards.
Before installing, assume your searches and retrieved contact records are sent to and processed by Upkuajing, may incur charges, and may be saved locally. Do not print the .env file, restrict permissions on ~/.upkuajing and task_data, delete retained result files when no longer needed, and use the contact data only where privacy and anti-spam rules allow it.
scripts/auth.py:60API Key May Be Exposed Through Terminal Output and Permissive File Permissions
scripts/common.py:399Personal and Contact Search Results Are Persisted Without Explicit Access Controls or Retention Limits
requirements.txt:1Open-Ended Dependency Constraint Allows Unreviewed Future Releases
The documented behavior includes remote version checks, parsing local SKILL metadata, and maintaining a version cache on disk, none of which are reflected in the declared search-oriented purpose. While less severe than credential or billing issues, undisclosed update-check and cache behavior expands network and file access beyond user expectations.
The documented behavior includes remote version checks, parsing local SKILL metadata, and maintaining a version cache on disk, none of which are reflected in the declared search-oriented purpose. While less severe than credential or billing issues, undisclosed update-check and cache behavior expands network and file access beyond user expectations.
The documented behavior includes remote version checks, parsing local SKILL metadata, and maintaining a version cache on disk, none of which are reflected in the declared search-oriented purpose. While less severe than credential or billing issues, undisclosed update-check and cache behavior expands network and file access beyond user expectations.
The instructions direct reading a credential file from ~/.upkuajing/.env and even show using cat to inspect it. Encouraging direct access to raw secret storage increases the chance the API key is exposed to the agent, logs, terminal history, screenshots, or unintended downstream output.
使用此技能需要API密钥。API密钥保存在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
The skill asks the agent to check for a secret in ~/.upkuajing/.env and, if absent, to create and store a new API key automatically. This combines credential discovery with credential creation and local persistence, expanding the blast radius if the agent environment is compromised or if file access is broader than intended.
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
The workflow instructs manual addition of an API key to a local .env file or automatic saving of a newly issued key there. Plaintext credential storage in a predictable home-directory path materially increases risk of theft via overbroad file permissions, other tools on the host, backups, or accidental disclosure during troubleshooting.
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
### **账户充值**
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 script writes a newly issued API key directly into a .env file without showing any permission hardening or atomic secure creation. If that file is created with permissive defaults or in a shared environment, other local users/processes may read the credential and abuse the associated 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'
# 日志开关
The skill documents capabilities to read environment variables, access local files under the user's home directory, write credential/cache files, and make network calls, but it does not declare any explicit tool scope or allowed-tools boundary. That omission weakens least-privilege controls and makes it harder for a host system or reviewer to constrain the skill to only the minimum operations required.
The skill explicitly enables retrieval of personal contact information including email, phone, and WhatsApp without an accompanying privacy, lawful-use, or compliance warning. In this context, the capability is more dangerous because the skill is aimed at lead generation and people search, which raises risks of privacy violations, spam, and misuse of personal data across jurisdictions.
The API documentation explicitly encourages sending request parameters, response data, and error context to an error-reporting endpoint, and although it mentions automatic masking of sensitive fields, it does not define what is masked or warn users not to include personal or regulated data. In this skill’s context—global company and people search, including emails, phone numbers, and WhatsApp details—those payloads can easily contain PII or sensitive business data, so error reporting can become an unintended data exfiltration channel.
技能清单描述聚焦于搜索全球企业信息、个人信息及联系方式,用于获客、背调和人才搜索;而本文件模块说明与代码实际实现的是 API 密钥申请、账户信息查询、充值订单创建和接口定价查询。认证与计费管理并非该搜索能力的自然语义组成部分,因此与技能对外宣称的用途存在明显偏离。
This Python file contains user-facing natural-language strings exclusively in Chinese, including the module description and command help text. The policy requires flagging language or locale constraints when the skill forces a specific language without user opt-in, and this file provides no alternative language option or justification for the restriction.
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:
account_info、new_rec_order 和 price_info 分别访问账户资料、余额、支付链接和接口定价信息,这些都是平台商业账户管理能力,而非搜索企业或个人资料所必需的核心功能。对于一个面向信息检索与线索开发的技能来说,内置充值与计费查询属于上下文不相称的扩展能力。
The file's natural-language content, including the module description and user-facing error/help strings, is written only in Chinese, which imposes a language choice on users without opt-in. Under the language policy, this can be a locale/language constraint unless the skill explicitly offers alternatives or documents that it is region-specific.
make_request sends caller-provided params to a remote third-party API, and this skill’s purpose is specifically to search for company and personal contact information. Without an explicit disclosure or consent check at the call site, users may unknowingly transmit sensitive search terms, identifiers, or personal data off-device to an external service.
This code file contains natural-language docstrings and CLI descriptions entirely in Chinese, including the skill title and usage text, with no indication that the language is selectable or that the skill is intentionally restricted to Chinese-speaking users. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.
Detected: suspicious.exposed_secret_literal