T09 · Insecure Skill Coding Practices
- Location
scripts/text-to-image.sh:93- Finding
Unescaped prompt permits JSON request-body injection in text-to-image workflow
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This image-generation skill is mostly purpose-aligned, but it handles credentials and downloaded remote content unsafely enough that users should review it before installing.
Install only if you are comfortable sending prompts, reference image URLs, and your BizyAir API authorization to the BizyAir endpoint. Before use, remove API-key-prefix logging, replace string-built JSON with a JSON serializer, validate downloaded files before saving or opening them, and narrow the chmod permission to the exact scripts.
scripts/text-to-image.sh:93Unescaped prompt permits JSON request-body injection in text-to-image workflow
scripts/image-to-image.sh:135Unescaped prompts and image URLs permit JSON request-body injection in image-to-image workflow
scripts/text-to-image.sh:65Text-to-image script discloses an API key prefix in logs
scripts/image-to-image.sh:89Image-to-image script discloses an API key prefix in logs
scripts/text-to-image.sh:138Text-to-image workflow trusts and automatically opens unvalidated downloaded content
scripts/image-to-image.sh:193Image-to-image workflow trusts and automatically opens unvalidated downloaded content
.claude/settings.local.json:2Wildcard chmod permission violates least-privilege requirements
代码仅接收两个参数:提示词和比例。请求体里只包含 prompt 与 aspect_ratio,没有上传输入图片、参考图列表、图像混合参数或任何 image-to-image 相关字段,因此无法支持声明中的“图生图”“参考图片生成”“多图融合”。它确实实现了“文生图”“文本转图片”“设置图片尺寸比例”“生成横版/竖版图片”等子能力,但声明把技能描述成同时覆盖文生图与图生图工具,这与当前代码块实际行为不符。未发现额外危险或无关能力;问题主要是声明的功能范围大于实际实现。
The trigger conditions are extremely broad, including generic phrases like '帮我画一张' or '生成图片', which can cause the skill to activate on many everyday requests. In an agentic environment with shell and networked side effects, overbroad triggering increases the chance of unintended execution, external API calls, and data transmission without sufficiently specific user intent.
Referenced artifact was not completely inspected
调用脚本 `scripts/image-to-image.sh`:
Referenced artifact was not completely inspected
调用脚本 `scripts/image-to-image.sh`:
Referenced artifact was not completely inspected
调用脚本 `scripts/image-to-image.sh`:
Referenced artifact was not completely inspected
调用脚本 `scripts/image-to-image.sh`:
The skill instructs the agent to execute shell scripts, but the manifest does not declare any explicit tool scope such as allowed-tools or permissions. This creates an authorization and review gap: consumers cannot easily tell that code execution is required, and a broadly empowered runtime may permit unintended command execution paths.
The skill sends user prompts and possibly reference image URLs to a third-party external API, which is a real data egress path. In this context, the transmission is part of the intended functionality, but it still poses privacy and compliance risk if users are not clearly informed that their content will leave the local environment and be processed by an external provider.
| 参数 | 值 |
|------|-----|
| 端点 | `https://api.bizyair.cn/w/v1/webapp/task/openapi/create` |
| web_app_id | `52416` |
| 模型 | BizyAir_GPT_IMAGE_2_T2I_API |
| 提示词键 | `4:BizyAir_GPT_IMAGE_2_T2I_API.prompt` |
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# ========================================
# 创建pic文件夹(如果不存在)
# ========================================
mkdir -p pic
# ========================================
# 从环境变量获取API密钥
The script prints the first 8 characters of the API key to stdout, unnecessarily disclosing part of a secret. Logs may be captured by terminals, CI systems, shared shells, agent telemetry, or support bundles, making partial credential leakage easier to correlate and exploit alongside other exposed data.
The script transmits user prompts, image URLs, and the bearer API credential to an external third-party service. In the context of an image-generation skill this is expected functionality, but it still creates a real data-exposure boundary: sensitive prompts, private image references, and credentials leave the local environment and depend on the remote provider's security and privacy controls.
# --connect-timeout: 连接超时 30 秒
# --max-time: 总请求超时 600 秒(10 分钟),覆盖最慢情况
print_info "正在等待 API 响应(预计 90秒 ~ 10分钟)..."
RESPONSE=$(curl -s --connect-timeout 30 --max-time 600 -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "$JSON_PAYLOAD")
The script transmits user prompts, image URLs, and the bearer API credential to an external third-party service. In the context of an image-generation skill this is expected functionality, but it still creates a real data-exposure boundary: sensitive prompts, private image references, and credentials leave the local environment and depend on the remote provider's security and privacy controls.
# --connect-timeout: 连接超时 30 秒
# --max-time: 总请求超时 600 秒(10 分钟),覆盖最慢情况
print_info "正在等待 API 响应(预计 90秒 ~ 10分钟)..."
RESPONSE=$(curl -s --connect-timeout 30 --max-time 600 -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "$JSON_PAYLOAD")
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# ========================================
# 创建pic文件夹(如果不存在)
# ========================================
mkdir -p pic
# ========================================
# 从环境变量获取API密钥
The script prints the first 8 characters of the API key to the console, unnecessarily exposing secret material during normal operation. Even partial credential disclosure can aid attackers through log scraping, screenshot leaks, shared terminal history, or correlation with other leaked data, and this exposure is not required for an image-generation tool to function.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# --connect-timeout: 连接超时 30 秒
# --max-time: 总请求超时 600 秒(10 分钟),覆盖最慢情况
print_info "正在等待 API 响应(预计 90秒 ~ 10分钟)..."
RESPONSE=$(curl -s --connect-timeout 30 --max-time 600 -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "$JSON_PAYLOAD")
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# --connect-timeout: 连接超时 30 秒
# --max-time: 总请求超时 600 秒(10 分钟),覆盖最慢情况
print_info "正在等待 API 响应(预计 90秒 ~ 10分钟)..."
RESPONSE=$(curl -s --connect-timeout 30 --max-time 600 -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "$JSON_PAYLOAD")
All user-facing usage and status documentation in the script header is presented only in Chinese, with no indication that language is configurable or optional. This can violate language/locale policy when a skill imposes a specific language without user opt-in.
The manifest describes an image-generation skill using the BizyAir GPT_IMAGE_2 API, but it does not mention accessing environment variables for credentials. While network access is expected for this purpose, reading local environment state is an additional capability that is not explicitly justified by the stated user-facing purpose.