Back to skill

Security audit

ssy-batchjob-async-job

Security checks for vulnerabilities and agentic risk

Overview

This skill does the BatchJob work it advertises, but it can automatically upload local files or URL-fetched content to a configured external service with too little user confirmation or destination validation.

Install only if you trust the BatchJob endpoint and token configuration and are comfortable with the agent automatically uploading selected or context-resolved files. Prefer using explicit file_id values or clearly chosen workspace files, avoid sensitive local paths, and require operator review before using this skill with private datasets, internal URLs, or broadly privileged agent runtimes.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:148
Finding
Unrestricted URL Retrieval Enables SSRF and Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 95-96 and 148-153 **Vulnerability Type**: Server-Side Request Forgery and unintended data disclosure **Risk Level**: High ### Vulnerable Code ```text 2. Public `file_url` (`http://` or `https://`): - download to temp local file, then upload. ``` ```bash FILE_URL="https://example.com/input.jsonl" EXT="${FILE_URL##*.}" FILE_PATH="$(mktemp "/tmp/batchjob-input.XXXXXX.${EXT:-jsonl}")" curl -fL --retry 3 --connect-timeout 10 "$FILE_URL" -o "$FILE_PATH" ``` ### Technical Analysis The Skill instructs the Agent to download any user-provided HTTP or HTTPS URL. Although the source is described as “public,” no technical control enforces that restriction. The `curl` command follows redirects through `-L`, but the Skill does not require validation of either the initial URL or subsequent redirect destinations. It does not reject: - Loopback addresses such as `127.0.0.1` and `::1` - RFC1918 private networks - Link-local addresses - Cloud metadata services - Internal DNS names - Redirects from public hosts to private addresses - Plaintext HTTP sources After retrieval, the normal execution flow treats the downloaded file as an upload source. Consequently, this behavior can combine SSRF with exfiltration: content obtained from an internal service can be transmitted to the configured BatchJob endpoint. URL retrieval is needed for the declared public-file workflow, but unrestricted access to arbitrary network locations exceeds the minimum privilege required to download genuinely public datasets. ### Attack Path 1. An attacker supplies an HTTP or HTTPS URL as the BatchJob input source. 2. The URL directly references an internal resource or redirects to one. 3. The Agent executes `curl -fL` and retrieves the resource from its own network context. 4. The downloaded response is saved as a temporary local file. 5. The file resolver returns that path to the upload workflow. 6. The Agent Base64-encodes t ...[truncated 718 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Accept only `https://` source URLs unless plaintext HTTP is explicitly required and approved. 2. Parse URLs with a dedicated URL parser rather than relying on string-prefix checks. 3. Resolve the hostname before connecting and reject: - Loopback ranges - Private IPv4 and IPv6 ranges - Link-local ranges - Multicast and reserved ranges - Known cloud metadata addresses 4. Validate every redirect target before following it. Do not rely on validation of only the initial URL. 5. Prefer an allowlist of approved dataset-hosting domains. 6. Protect against DNS rebinding by validating resolved addresses and ensuring the connection uses the validated destination. 7. Set strict response-size and download-time limits. 8. Require explicit user confirmation before uploading remotely retrieved content, showing the final resolved source hostname. 9. Keep the download and BatchJob upload as separately authorized operations rather than automatically chaining them. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:185
Finding
Automatic Upload of Arbitrary Readable Local Files Violates Least Privilege<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 30-33, 97-102, 121-123, and 185-193 **Vulnerability Type**: Unauthorized local-file access and external disclosure **Risk Level**: High ### Vulnerable Code ```text - Always run in full-auto mode. - Do not ask user for `file_id` first. - Resolve file source from current message/context, then upload automatically when needed. - Ask follow-up questions only when no readable file source can be obtained. ``` ```text 3. Explicit local `file_path`: - if readable, upload. 4. Inbound attachment local path from channel/runtime context: - examples: `/tmp/...`, `MEDIA:<path>`, `/tmp/openclaw-media/...`. - if readable, upload. ``` ```bash FILE_PATH="/path/to/input.jsonl" FILE_NAME="$(basename "${FILE_PATH}")" test -f "${FILE_PATH}" || { echo "文件 ${FILE_PATH} 不存在"; exit 1; } FILE_CONTENT_B64="$(base64 < "${FILE_PATH}" | tr -d '\n')" curl -sS "${BATCHJOB_BASE_URL}/v1/batch/files:upload" \ -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"filename\":\"${FILE_NAME}\",\"mode\":\"fast\",\"content\":\"${FILE_CONTENT_B64}\"}" ``` ### Technical Analysis The resolver accepts an explicit local path whenever it is readable and then automatically uploads its contents. No restriction confines access to a dedicated upload directory, the current workspace, or verified channel attachments. The only illustrated validation is `test -f`, which establishes that the target is a regular file but does not establish that: - The user is authorized to disclose it - The path belongs to the current task - The file is inside an approved directory - The path did not escape through a symbolic link - The file avoids known credential or configuration locations - Its size and actual format are appropriate for BatchJob - A path appearing in message context constitutes explicit upload consent The full-auto policy worsens the exposure by discouraging confirmation whene ...[truncated 1497 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict upload sources to dedicated, approved roots such as: - The current task workspace - A specific inbound-attachment directory - A newly created temporary directory controlled by the Skill 2. Canonicalize paths before access and verify that the canonical result remains under an approved root. 3. Reject symbolic links or securely resolve them before performing the directory-boundary check. 4. Deny sensitive locations explicitly, including credential stores, SSH directories, environment files, service-account files, and system configuration directories. 5. Require explicit confirmation before upload. Display the canonical path, filename, size, and destination host. 6. Treat a path appearing in conversational context as a candidate source, not authorization to disclose it. 7. Verify actual file format rather than relying only on the extension. 8. Enforce strict file-size and row-count limits before reading the complete file into memory. 9. Run the Skill under a sandboxed operating-system identity with access only to task-specific files. 10. Prefer runtime-issued attachment handles over arbitrary filesystem paths. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:190
Finding
Unvalidated BatchJob Base URL Can Expose Bearer Tokens and Uploaded Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 13-19 and 190-216 **Vulnerability Type**: Untrusted destination and insecure transport configuration **Risk Level**: High ### Vulnerable Code ```text - `BATCHJOB_BASE_URL` - `BATCHJOB_BEARER_TOKEN` All HTTP requests must include: ```bash -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" -H "Content-Type: application/json" ``` ``` ```bash curl -sS "${BATCHJOB_BASE_URL}/v1/batch/files:upload" \ -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"filename\":\"${FILE_NAME}\",\"mode\":\"fast\",\"content\":\"${FILE_CONTENT_B64}\"}" ``` ```bash curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs:precheck" \ -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"record_count": 100, "model": "google/gemini-2.5-flash-image", "mode": "fast"}' ``` ```bash curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs" \ -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"file_id": "your-file-id", "model": "google/gemini-2.5-flash-image", "mode": "fast"}' ``` ```bash curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs/${JOB_ID}" \ -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" ``` ```bash curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs/${JOB_ID}:cancel" \ -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"reason":"user requested cancellation"}' ``` ### Technical Analysis The Skill obtains `BATCHJOB_BASE_URL` from the environment and concatenates API paths onto it without requiring HTTPS or validating the destination hostname, port, or URL structure. Every request includes the bearer token, while the upload request additionally includes the complete Base64-encoded dataset. If the environment variable is incorrectly configured, influenced by an untrusted deployment component, or points to plaintext HTTP, credentials ...[truncated 1607 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require `BATCHJOB_BASE_URL` to use `https://`. 2. Parse and validate the URL before any request. 3. Allowlist the official BatchJob hostname or a narrowly defined set of approved enterprise endpoints. 4. Reject embedded credentials, fragments, unexpected paths, and unapproved ports. 5. Normalize the base URL before appending API routes. 6. Use a bearer token scoped only to the minimum required BatchJob operations and environment. 7. Rotate credentials immediately if they may have been sent to an untrusted endpoint. 8. Avoid logging command lines, request headers, or request bodies containing credentials and datasets. 9. Add a startup validation step that fails closed before reading any local file if endpoint verification fails. 10. Where possible, use endpoint-specific credentials so that a token configured for one host is never accepted for another. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- OpenAI Batch style lines containing `method` + `url` + `body` (for example `/v1/chat/completions` payload).
  - This schema will fail with Vertex error: `at least one contents field is required`.

## Dataset Output Rule (Important)

When user asks you to generate a template/demo file for BatchJob image tasks:
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill explicitly directs the agent to resolve files from message/context, download them if needed, upload their contents, and proceed to precheck/submit in full-auto mode without requiring an explicit user confirmation at the point of data transmission. This creates a real risk of unintentionally sending sensitive local files, attachments, or URL-fetched content to an external BatchJob service without sufficiently informed consent.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Automation Policy (Default)

- Always run in full-auto mode.
- Do not ask user for `file_id` first.
- Resolve file source from current message/context, then upload automatically when needed.
- Ask follow-up questions only when no readable file source can be obtained.
- Accepted input file formats for upload: `jsonl`, `csv`, `xlsx`, `xls` (BatchJob normalizes to internal JSONL).
Confidence
91% confidence
Finding
The instruction to always run in full-auto mode and avoid asking the user first is a genuine unsafe-autonomy issue in a skill that can fetch files, upload them externally, and submit jobs. By reducing user checkpoints, it increases the chance of unintended external actions, privacy violations, and misuse of attached or local files.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The skill includes a fixed Chinese fallback prompt for user interaction, which imposes a specific language on users. There is no indication that the skill is region-specific or that the user can opt into Chinese versus another language.

External Transmission

Medium
Category
Data Exfiltration
Content
test -f "${FILE_PATH}" || { echo "文件 ${FILE_PATH} 不存在"; exit 1; }
FILE_CONTENT_B64="$(base64 < "${FILE_PATH}" | tr -d '\n')"

curl -sS "${BATCHJOB_BASE_URL}/v1/batch/files:upload" \
  -H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"filename\":\"${FILE_NAME}\",\"mode\":\"fast\",\"content\":\"${FILE_CONTENT_B64}\"}"
Confidence
95% confidence
Finding
This code base64-encodes a local file and sends its full contents to an external endpoint using a bearer token. In the broader skill context, this transmission is dangerous because the skill is designed to automatically resolve local paths, attachments, and public URLs, so sensitive data could be exfiltrated to a third-party service with minimal user interaction.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The short description is written only in Chinese, which indicates a language-specific presentation without any visible opt-in, alternative locale, or justification in this file. The policy requires flagging language or locale constraints when the skill appears to force a specific language without user choice.

Static analysis

Detected: suspicious.generated_source_template_injection

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
SKILL.md:186