T09 · Insecure Skill Coding Practices
- Location
SKILL.md:102- Finding
API Key Exposure Through Credential File Output and Insecure File Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This SMS skill appears purpose-related, but it handles paid messaging, account actions, and API keys in ways that need careful review before use.
Install only if you trust the Upkuajing service with recipient phone numbers, SMS content, delivery records, and paid account operations. Do not run commands that print ~/.upkuajing/.env, do not pass real API keys with --api_key, restrict the credential file permissions, and require a separate explicit confirmation for every paid SMS send or recharge flow.
SKILL.md:102API Key Exposure Through Credential File Output and Insecure File Permissions
scripts/sms_send.py:87API Keys Can Be Supplied Through Observable Command-Line Arguments
requirements.txt:1Unbounded Third-Party Dependency Allows Unreviewed Future Releases
scripts/version_check.py:95Undisclosed Automatic Version Telemetry and Persistent Home-Directory State
The skill description presents a narrow SMS-sending/status purpose, but the document also includes credential provisioning, local secret persistence, account management, recharge order creation, and error-reporting flows. This mismatch can mislead users and agents about what actions the skill may take, increasing the chance of consent bypass for sensitive or billable operations.
The skill description presents a narrow SMS-sending/status purpose, but the document also includes credential provisioning, local secret persistence, account management, recharge order creation, and error-reporting flows. This mismatch can mislead users and agents about what actions the skill may take, increasing the chance of consent bypass for sensitive or billable operations.
The skill description presents a narrow SMS-sending/status purpose, but the document also includes credential provisioning, local secret persistence, account management, recharge order creation, and error-reporting flows. This mismatch can mislead users and agents about what actions the skill may take, increasing the chance of consent bypass for sensitive or billable operations.
The skill description presents a narrow SMS-sending/status purpose, but the document also includes credential provisioning, local secret persistence, account management, recharge order creation, and error-reporting flows. This mismatch can mislead users and agents about what actions the skill may take, increasing the chance of consent bypass for sensitive or billable operations.
The skill description presents a narrow SMS-sending/status purpose, but the document also includes credential provisioning, local secret persistence, account management, recharge order creation, and error-reporting flows. This mismatch can mislead users and agents about what actions the skill may take, increasing the chance of consent bypass for sensitive or billable operations.
The skill explicitly instructs reading a local .env file containing an API key. Exposing or encouraging access to raw secret material is dangerous because it can leak credentials through logs, model responses, screenshots, or downstream tool calls, enabling unauthorized use of the SMS account and related services.
使用此技能需要API密钥。API密钥保存在 ~/.upkuajing/.env 文件中:
cat ~/.upkuajing/.env
文件内容示例:
The workflow instructs checking for a local API key and, if absent, automatically applying for a new key and saving it to ~/.upkuajing/.env. Automatic secret creation and persistence in a general local file increases attack surface, risks accidental disclosure, and blends account provisioning with ordinary tool use without strong trust boundaries.
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
This section continues the secret-handling pattern by directing the agent to inspect and populate a local .env file with UPKUAJING_API_KEY. In context, the danger is heightened because the same skill also performs outbound network and billable operations, so a leaked key can directly enable unauthorized messaging, account actions, and potential financial abuse.
请先检查 `~/.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():
This line persists a newly created API key in plaintext to a local .env file. Plaintext secret storage can expose the credential to other local users, misconfigured permissions, backups, or accidental inclusion in diagnostic output or repository files.
"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 declares access to environment variables and explicitly instructs reading and writing local credential files and making network requests, but it does not declare any tool scope or allowed-tools restrictions. This weakens least-privilege controls and makes accidental or unauthorized file, secret, and network access harder to constrain or audit.
技能名称带有“zh”,全文说明也仅以中文提供,且未声明这是可选语言模式或仅面向特定中文场景。根据语言/locale 政策,若技能实际上强制使用单一语言而不给用户选择,可能构成自然语言策略违规。
The manifest description focuses on sending SMS and viewing status, but the body also directs API-key application and recharge order creation. Expanding from messaging into credential issuance and payment-adjacent workflows without clear up-front disclosure increases the risk of unexpected sensitive actions.
The document says the skill provides three SMS scripts, but later instructs the agent to perform additional actions like key issuance, pricing lookup, account info access, recharge order creation, and error reporting. This creates a deceptive interface boundary that can cause users to authorize a messaging tool without realizing it also performs secret management and financial/account operations.
The skill handles phone numbers and message content and sends them to external telecom-related services, yet the description does not clearly warn users about data externalization, privacy implications, or compliance obligations. In a messaging context, this omission is significant because the processed data is often personal, regulated, and cross-border.
Recharge order creation is a payment-related action that is not essential to the core task of sending or checking SMS messages. In skill ecosystems, hidden or loosely scoped financial operations are especially risky because they can trigger unintended charges, phishing-like payment flows, or social engineering around payment URLs.
Broad natural-language trigger guidance can cause the agent to invoke this skill in response to ambiguous everyday requests. Because the skill can access credentials, contact data, and billable SMS operations, accidental invocation raises privacy, consent, and cost risks.
The documentation explicitly allows sending request parameters, response data, and exception context to an error-reporting endpoint, which can easily include customer phone numbers, message contents, API payloads, tokens, or stack traces containing secrets. Although it mentions that sensitive fields are 'automatically desensitized', it does not define what is treated as sensitive, does not require minimization, and provides no clear warning or consent guidance before transmitting potentially private data off-path for diagnostics.
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