Back to skill

Security audit

bozo-jiaodu

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a camera-angle prompt helper, but it also includes credentialed remote image-processing scripts and hidden local agent permission settings that users should review before installing.

Install only if you intend to use BizyAir for remote image angle editing, understand that image URLs, prompts, request IDs, and output URLs may be sent to or fetched from BizyAir, and are comfortable granting shell/curl access with a BIZYAIR_API_KEY. Review or remove the hidden .claude/settings.local.json and harden the scripts before using them with sensitive images, private URLs, or paid API credentials.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create_angle_task.sh:42
Finding
Unescaped User Input Permits JSON Request Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/create_angle_task.sh:42-57` **Vulnerability Type**: Improper construction of JSON from untrusted input **Risk Level**: Medium ### Vulnerable Code ```bash # 获取参数 IMAGE_URL="$1" CAMERA_PROMPT="$2" WEB_APP_ID="${3:-43531}" # 验证摄像机提示词格式 if [[ ! "$CAMERA_PROMPT" =~ ^\<sks\>\ .+ ]]; then echo -e "${RED}❌ 错误: 摄像机提示词必须以 <sks> 开头${NC}" echo "💡 正确格式示例: <sks> left side view low-angle shot close-up" exit 1 fi # 构建请求数据 REQUEST_DATA=$(cat <<EOF { "web_app_id": ${WEB_APP_ID}, "suppress_preview_output": false, "input_values": { "41:LoadImage.image": "${IMAGE_URL}", "112:TextEncodeQwenImageEditPlus.prompt": "${CAMERA_PROMPT}\n" } } EOF ) ``` ### Technical Analysis The script directly interpolates three command-line arguments into a JSON document: - `IMAGE_URL` is inserted into a JSON string without JSON escaping. - `CAMERA_PROMPT` is inserted into a JSON string without JSON escaping. - `WEB_APP_ID` is inserted as raw JSON without numeric validation or an allowlist. The prompt validation only confirms that the value begins with `<sks> `. It does not restrict the remainder to one of the documented 96 prompts and does not prevent quotes, backslashes, newlines, or JSON syntax from appearing after the prefix. Consequently, a caller can terminate the intended JSON string or provide an arbitrary JSON expression through `WEB_APP_ID`. The modified payload is then transmitted using the legitimate `BIZYAIR_API_KEY` in the authorization header. This is JSON injection rather than shell command injection: shell metacharacters inside the variables are not reparsed as commands, but they can alter the API request body. ### Attack Path 1. The attacker gains the ability to influence arguments passed to `create_angle_task.sh`, such as through an agent-generated invocation or an application wrapper. 2. The attacker supplies a crafted image URL, prompt, or workflow ID containing JSON delimiters an ...[truncated 1040 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Construct the request with a real JSON serializer such as `jq`: ```bash if [[ ! "$WEB_APP_ID" =~ ^[0-9]+$ ]]; then echo "Invalid web_app_id" >&2 exit 1 fi case "$WEB_APP_ID" in 43531) ;; *) echo "Unsupported web_app_id" >&2 exit 1 ;; esac REQUEST_DATA="$( jq -n \ --argjson web_app_id "$WEB_APP_ID" \ --arg image_url "$IMAGE_URL" \ --arg prompt "${CAMERA_PROMPT}"$'\n' \ '{ web_app_id: $web_app_id, suppress_preview_output: false, input_values: { "41:LoadImage.image": $image_url, "112:TextEncodeQwenImageEditPlus.prompt": $prompt } }' )" ``` 2. Validate `CAMERA_PROMPT` against an exact allowlist of the 96 supported values rather than checking only its prefix. 3. Restrict `WEB_APP_ID` to the required workflow ID, or to a small explicit allowlist if multiple workflows are necessary. 4. Validate `IMAGE_URL` as an HTTPS URL and, where feasible, restrict its hostname to approved image-storage domains. 5. Reject control characters and enforce reasonable maximum lengths for all arguments. 6. Use `curl --fail-with-body` and verify that serialization succeeded before sending the authenticated request. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/get_task_outputs.sh:33
Finding
Unbounded Polling and Unvalidated Parameters Permit API Request Amplification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get_task_outputs.sh:33-127` **Vulnerability Type**: Uncontrolled resource consumption and improper URL parameter handling **Risk Level**: Low ### Vulnerable Code ```bash # 获取参数 REQUEST_ID="$1" POLL_INTERVAL="${2:-5}" echo -e "${BLUE}🔍 查询任务结果...${NC}" echo "🔖 任务 ID: ${REQUEST_ID}" echo "⏱️ 轮询间隔: ${POLL_INTERVAL} 秒" echo "" # 轮询查询任务状态 while true; do # 获取任务状态 RESPONSE=$(curl -s -X GET "https://api.bizyair.cn/w/v1/webapp/task/openapi/outputs?requestId=${REQUEST_ID}" \ -H "Authorization: Bearer ${BIZYAIR_API_KEY}") ``` The loop later retries without a maximum attempt count: ```bash elif [ "$STATUS" = "Pending" ] || [ "$STATUS" = "Processing" ] || [ "$STATUS" = "Accepted" ]; then echo -e "${YELLOW}⏳ 任务进行中... (${STATUS})${NC}" echo "💡 等待 ${POLL_INTERVAL} 秒后重新查询..." echo "" sleep $POLL_INTERVAL elif [ -z "$STATUS" ]; then # 无法解析状态,可能任务不存在或 API 返回格式变化 echo -e "${YELLOW}📡 无法解析任务状态${NC}" echo "API 响应: ${RESPONSE}" echo "" echo "💡 请确认任务 ID 是否正确" exit 1 else echo -e "${YELLOW}📡 未知状态: ${STATUS}${NC}" echo "API 响应: ${RESPONSE}" echo "" echo "💡 等待 ${POLL_INTERVAL} 秒后重新查询..." echo "" sleep $POLL_INTERVAL fi done ``` ### Technical Analysis `POLL_INTERVAL` is accepted without confirming that it is a positive integer within a safe range. An interval of `0` causes the script to issue authenticated requests continuously while a task remains pending or returns an unknown nonempty status. Invalid or negative values can make `sleep` fail immediately, after which the loop continues and can have the same rapid-retry effect. The `while true` loop has no maximum retry count or overall deadline. A task that remains pending indefinitely can therefore keep the process and API polling active without limit. In addition, `REQUEST_ID` is directly concatenated ...[truncated 1796 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require a strictly positive, bounded integer polling interval: ```bash POLL_INTERVAL="${2:-5}" if [[ ! "$POLL_INTERVAL" =~ ^[0-9]+$ ]] || (( POLL_INTERVAL < 2 || POLL_INTERVAL > 300 )); then echo "Polling interval must be an integer from 2 to 300 seconds." >&2 exit 1 fi ``` 2. Add a maximum retry count and an overall deadline: ```bash MAX_ATTEMPTS=120 ATTEMPT=0 while (( ATTEMPT < MAX_ATTEMPTS )); do ATTEMPT=$((ATTEMPT + 1)) # Perform request and process status. done echo "Polling timed out after ${MAX_ATTEMPTS} attempts." >&2 exit 1 ``` 3. Validate the expected request-ID format. If UUIDs are expected, enforce the UUID syntax. 4. URL-encode the request ID rather than concatenating it into the URL. For example: ```bash RESPONSE=$(curl \ --silent \ --show-error \ --fail-with-body \ --connect-timeout 10 \ --max-time 30 \ --get \ --data-urlencode "requestId=${REQUEST_ID}" \ -H "Authorization: Bearer ${BIZYAIR_API_KEY}" \ "https://api.bizyair.cn/w/v1/webapp/task/openapi/outputs") ``` 5. Quote the sleep argument after validation: ```bash sleep "$POLL_INTERVAL" ``` 6. Apply exponential backoff with a reasonable upper bound for repeated pending responses. 7. Terminate after repeated network failures or unrecognized statuses rather than retrying indefinitely. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill is presented as a text-formatting assistant but also includes asynchronous task polling, authenticated status retrieval, and result rendering from an external service. That discrepancy undermines trust boundaries and can cause the agent to use secrets and transmit user data in contexts where only local text transformation was expected.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill is presented as a text-formatting assistant but also includes asynchronous task polling, authenticated status retrieval, and result rendering from an external service. That discrepancy undermines trust boundaries and can cause the agent to use secrets and transmit user data in contexts where only local text transformation was expected.

Vague Triggers

High
Confidence
95% confidence
Finding
The catch-all rule '只要涉及到角度或视角,都必须参考96个摄像机位置提示词进行转换' lacks clear scope boundaries and can over-apply the skill to unrelated contexts. This increases the chance of incorrect routing, misleading outputs, or unintended execution paths when users mention angles in non-camera contexts.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill is described as a prompt-conversion helper, but this script performs a materially different action: it sends user-supplied image URLs and prompts to an external service to create and run image-editing tasks. This is dangerous because users and calling systems may grant the skill broader trust than intended, resulting in unexpected external processing of data and execution of side effects.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The script performs external task-result retrieval and exposes generated image URLs, which is materially broader than the declared role of a camera-angle prompt conversion skill. This kind of capability expansion increases data-flow risk because user-linked task identifiers and resulting content are sent to and fetched from a third-party service without being inherent to the stated transformation-only purpose.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents shell-based execution paths and direct curl usage but does not declare any tool scope or allowed-tools restrictions. In an agent environment, this mismatch can enable unintended command execution or broaden the skill’s effective capabilities beyond what reviewers and orchestrators expect.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The catch-all rule '只要涉及到角度或视角,都必须参考96个摄像机位置提示词进行转换' lacks clear scope boundaries and can over-apply the skill to unrelated contexts. This increases the chance of incorrect routing, misleading outputs, or unintended execution paths when users mention angles in non-camera contexts.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The documentation expands from simple prompt conversion into actually executing remote image-angle adjustment through BizyAir. This broadens the operational scope from harmless text assistance to authenticated third-party processing of user-supplied content, increasing privacy, compliance, and side-effect risk.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
A prompt conversion assistant does not need remote API invocation to fulfill its stated purpose, so adding that capability is unjustified privilege expansion. Unnecessary network/auth capabilities increase attack surface and create opportunities for user data transmission or secret misuse without clear necessity.

External Transmission

Medium
Category
Data Exfiltration
Content
### 直接 API 调用

如果不使用脚本,可以直接使用 curl 调用 API:

**创建任务**:
```bash
Confidence
90% confidence
Finding
The skill includes direct curl-based transmission of user-supplied image URLs and prompts to an external API using an environment-sourced bearer token. External transmission is sensitive here because the skill’s declared role does not prepare users or reviewers for third-party data sharing and authenticated network actions.

External Transmission

Medium
Category
Data Exfiltration
Content
**创建任务**:
```bash
curl -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${BIZYAIR_API_KEY}" \
  -d '{
Confidence
88% confidence
Finding
This endpoint reference is part of an authenticated outbound API call path to BizyAir, enabling transmission of user content and use of stored credentials. In context, the danger comes from hidden third-party communication embedded in a skill marketed as a local prompt converter.

External Transmission

Medium
Category
Data Exfiltration
Content
**查询结果**:
```bash
curl -X GET "https://api.bizyair.cn/w/v1/webapp/task/openapi/outputs?requestId=<requestId>" \
  -H "Authorization: Bearer ${BIZYAIR_API_KEY}"
```
Confidence
86% confidence
Finding
The output-query endpoint allows the skill to poll external job status and retrieve generated result URLs from a third-party service using bearer authentication. While normal for an API client, it is security-relevant here because it extends a text conversion skill into external stateful processing and data retrieval without clear scope declaration.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The file claims to convert prompts into the predefined 96 standard camera-position prompts, and that list separately includes 'elevated shot' entries and 'high-angle shot' entries. However, the mapping documents '高角度' as 'elevated shot' while also separately supporting 'high-angle' as 'high-angle shot', which conflicts with the apparent intent shown by eval examples such as L129-L130 expecting '高角度' to produce a high-angle result.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README instructs users to send image URLs and camera-angle prompts to the BizyAir external API, but it does not clearly disclose that user-provided content will leave the local/system boundary and be processed by a third party. This creates a privacy and data-governance risk, especially if users supply sensitive image URLs, private storage links, or confidential prompt content under the assumption that processing is local.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The user-facing comments, usage text, prompts, and status messages are all written in Chinese, which effectively forces a specific language for anyone using the skill. Under the policy, locale or language constraints should either be optional for the user or clearly justified as region-specific.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The script requires an API key and is capable of transmitting data to a third-party image-processing service, which exceeds the expected capability of a 'conversion-only' helper. In this context, the mismatch increases the risk of covert data exfiltration or unauthorized billable API usage because operators may not expect networked execution with credentials.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "🎬 摄像机提示词: ${CAMERA_PROMPT}"
echo ""

RESPONSE=$(curl -s -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${BIZYAIR_API_KEY}" \
  -d "$REQUEST_DATA")
Confidence
96% confidence
Finding
The script transmits user-controlled inputs, including the image URL and camera prompt, to an external API using a bearer token. External transmission is security-relevant here because the skill's stated purpose does not clearly disclose third-party processing, so users may unknowingly send potentially sensitive data off-platform.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "🎬 摄像机提示词: ${CAMERA_PROMPT}"
echo ""

RESPONSE=$(curl -s -X POST "https://api.bizyair.cn/w/v1/webapp/task/openapi/create" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${BIZYAIR_API_KEY}" \
  -d "$REQUEST_DATA")
Confidence
96% confidence
Finding
The script transmits user-controlled inputs, including the image URL and camera prompt, to an external API using a bearer token. External transmission is security-relevant here because the skill's stated purpose does not clearly disclose third-party processing, so users may unknowingly send potentially sensitive data off-platform.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
Beyond prompt conversion, the script parses task results and renders remote image output URLs and previews, demonstrating full task orchestration and image-editing workflow handling. That broader behavior creates unexpected side effects and data flow, making the skill more dangerous because it can process and expose remote outputs rather than merely transform text locally.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The inline documentation describes the component as part of a camera-angle prompt conversion skill, but the code actually polls an external service and retrieves outputs. This mismatch is dangerous because it can conceal actual behavior from reviewers and users, making it easier for unexpected data transmission and external dependencies to go unnoticed.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The script's help text, status messages, and usage guidance are all presented in Chinese only. This imposes a fixed language on all users without offering a locale choice or documenting a justified region-specific constraint.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The script requires an external API key to perform operations unrelated to the advertised prompt-conversion behavior, indicating hidden privileged capability. Even though the key is not printed, introducing credentialed external access in a mismatched skill increases the risk of unauthorized third-party operations and weakens trust boundaries around what the skill can do.

External Transmission

Medium
Category
Data Exfiltration
Content
# 轮询查询任务状态
while true; do
    # 获取任务状态
    RESPONSE=$(curl -s -X GET "https://api.bizyair.cn/w/v1/webapp/task/openapi/outputs?requestId=${REQUEST_ID}" \
      -H "Authorization: Bearer ${BIZYAIR_API_KEY}")

    # 解析状态 - 兼容不同的字段名和位置
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The skill requires outputs to use fixed English prompt tokens beginning with `<sks>` and does not mention any user opt-in or language choice. While this may be functional for the downstream tool, the file does not explicitly justify the language constraint or present it as a required format for interoperability.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
This JSON manifest describes the skill entirely in Chinese, and the included eval prompts also assume Chinese-language interaction. Under the policy, language constraints should be optional or clearly justified; this file does not indicate user opt-in or a documented region-specific limitation.

Static analysis

No suspicious patterns detected.