Back to skill

Security audit

Hidream Aigc

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches an AI media-generation client, but it has under-disclosed credential, endpoint, and persistence behavior that users should review before installing.

Review this skill before installing. Use only a process-scoped HIDREAM_AUTHORIZATION when possible, avoid asking an agent to write your token with the documented echo command, and do not set HIDREAM_ENDPOINT or OPENCLAW_ENDPOINT unless you fully trust the destination. Treat generated media saved under assets/ as persistent local data that may need manual cleanup.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/common/task_client.py:21
Finding

Arbitrary endpoint override can disclose bearer credentials and user media

Content
View full analysis
list[str]: images = [] if not value: return images for image in value.split(","): image = image.strip() if not image: continue if os.path.exists(image): # Security Note: Reading local file for base64 encoding try: with open(image, "rb") as f: image_bytes = f.read() image_base64 = base64.b64encode(image_bytes).decode("utf-8") images.append(image_base64) except Exception as e: raise ValueError(f"Failed to read image file '{image}': {e}") else: # Assume it's a URL or base64 string images.append(image) return images ``` ```python def submit_task_and_poll_result( payload: dict[str, Any], path: str, authorization, poll_timeout: int ) -> dict[str, Any]: authorization = authorization or get_token() if not authorization: raise ValueError( "Missing authorization. Run 'scripts/configure.py' or set HIDREAM_AUTHORIZATION." ) endpoint = f"{ENDPOINT}{path}" headers = _headers(authorization) # print(payload) submit_resp = requests.post(endpoint, json=payload, headers=headers, timeout=30) ``` ```python result_url = endpoint + "/results" start = time.time() while True: query_resp = requests.get( result_url, params={"task_id": task_id}, headers=headers, timeo ...[truncated 2590 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:35
Finding

Recommended credential command overwrites a shared environment file without securing it

Content
View full analysis
~/.openclaw/.env` ``` At `SKILL.md:45-48`: ```markdown - **401 Unauthorized (invalid token)**: The token is invalid or expired. Update it by writing the new token to `~/.openclaw/.env`: ```bash echo "HIDREAM_AUTHORIZATION=sk-..." > ~/.openclaw/.env ``` ``` ### Technical Analysis The `>` shell redirection truncates `~/.openclaw/.env` before writing the credential. Because this appears to be a shared OpenClaw environment file, the command can silently delete unrelated configuration or credentials. The command also does not create the parent directory safely or enforce mode `0600` on the resulting file. The file therefore inherits permissions determined by the current process and `umask`. In addition, entering the token directly in a shell command can expose it through shell history, terminal logging, process instrumentation, or agent conversation records. The project already contains `set_token()` in `scripts/common/config.py`, which applies mode `0600` after writing the dedicated JSON configuration. However, the documentation labels the less-safe shell operation as recommended. ### Attack Path 1. A user receives a missing-token or HTTP 401 error. 2. Following the Skill's recommended instructions, the user provides the token to the agent or enters the documented shell command. 3. Shell redirection truncates any existing `~/.openclaw/.env`. 4. The new file is created without an explicit restrictive permission mode. 5. Unrelated OpenClaw settings are lost, and the token may be readable by other local users depending on the effective `umask` and directory permissions. 6. The liter ...[truncated 621 chars]
Remediation
View remediation
~/.openclaw/.env` recommendation. 2. Do not instruct users to paste API credentials into agent-visible conversation text. 3. Provide a functional interactive configurator that reads the token with `getpass.getpass()`. 4. Store the token in the dedicated `~/.config/openclaw/hidream_config.json` file with mode `0600` and ensure its parent directory has mode `0700`. 5. Create files atomically with restrictive permissions from the outset rather than applying `chmod` only after a normal write. 6. If `.env` support must remain, update only the relevant key without truncating unrelated entries, preserve existing secure permissions, and use an atomic replacement. 7. Recommend process-scoped environment variables for temporary use where persistent storage is unnecessary. 8. Add warnings about shell history and prevent credentials from being logged. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/common/task_client.py:65
Finding

Credential setup and error handling reference a nonexistent configuration script

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (26)

Tainted flow: 'endpoint' from os.getenv (line 70, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request destination is derived from an environment-variable override (HIDREAM_ENDPOINT / OPENCLAW_ENDPOINT), allowing the code to send payloads and bearer credentials to an arbitrary host rather than the declared service. In this skill, that means local file-derived data and authorization tokens can be exfiltrated to an attacker-controlled endpoint if the runtime environment is influenced.

Content

Scanner excerpt · scripts/common/task_client.py (reported line 73)May include surrounding context.

python
endpoint = f"{ENDPOINT}{path}"
    headers = _headers(authorization)
    # print(payload)
    submit_resp = requests.post(endpoint, json=payload, headers=headers, timeout=30)
    if submit_resp.status_code != 200:
        raise RuntimeError(f"http error: {submit_resp.status_code} {submit_resp.text}")
    resp_json = submit_resp.json()

Tainted flow: 'result_url' from os.getenv (line 87, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The polling URL inherits the same environment-controlled endpoint, so follow-up requests containing the authorization header are also sent to any attacker-specified host. This extends the exposure beyond the initial submission and can leak task metadata and credentials repeatedly during polling.

Content

Scanner excerpt · scripts/common/task_client.py (reported line 90)May include surrounding context.

python
result_url = endpoint + "/results"
    start = time.time()
    while True:
        query_resp = requests.get(
            result_url,
            params={"task_id": task_id},
            headers=headers,

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

There is a material description-to-behavior mismatch. The declared description says this skill is an OpenClaw AIGC client using vivago.ai, requiring HIDREAM_AUTHORIZATION and reading local image/video files for base64 encoding. The supplied code instead acts as an adapter around a Kling image-to-video function, taking structured JSON input from stdin with a prompt and image_input, then returning a video URL. While the underlying imported implementation may perform network access or credential use, this code chunk itself is specifically a Kling wrapper and does not align with the declared service, resource access pattern, or stated breadth of functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description says this skill is an OpenClaw AIGC client for both video and image models, with credential requirements, local file reading for base64 encoding, and requests sent to vivago.ai. This code chunk instead acts as an adapter around a Seedream text-to-image function: it parses JSON from STDIN, extracts prompt fields, invokes run_seedream with fixed parameters, validates the returned structure, and emits JSON containing an image URL. There is no file reading logic, no video handling, and no direct evidence of vivago.ai access or HIDREAM_AUTHORIZATION usage in this chunk. Because the code’s primary function and resource access differ materially from the declared description, this is a mismatch.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The security disclosure says no filesystem access occurs beyond reading provided files, but later instructions direct writing both credentials and generated output. This contradictory disclosure materially undermines trust and can cause agents or reviewers to permit actions they would otherwise restrict, masking persistent secret storage and file creation behavior.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill instructs storing an API token in a local .env file, creating persistent credential material on disk that may be exposed through backups, misconfigured permissions, later tool access, or accidental disclosure. Because the token enables authenticated requests to an external service, compromise of this file could directly lead to account abuse or billing impact.

Content

Scanner excerpt · SKILL.md (reported line 47)May include surrounding context.

md
- **Resolution too small (ValueError)**: Seedream M2 requires high resolution (at least `2560*1440` or `2048*2048`). If you get this error, increase the `resolution` parameter.
- **401 Unauthorized (invalid token)**: The token is invalid or expired. Update it by writing the new token to `~/.openclaw/.env`:
    ```bash
    echo "HIDREAM_AUTHORIZATION=sk-..." > ~/.openclaw/.env
    ```
- **Insufficient Credits (Code 2007)**: Instruct the user to go to `https://vivago.ai/platform/info` to recharge credits.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common/config.py (reported line 26)May include surrounding context.

python
Priority:
    1. HIDREAM_AUTHORIZATION env var
    2. OPENCLAW_AUTHORIZATION env var (legacy)
    3. ~/.openclaw/.env (Fallback)
    4. ~/.config/openclaw/hidream_config.json (unified config)
    """
    # 1. Check Env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common/config.py (reported line 34)May include surrounding context.

python
Priority:
    1. HIDREAM_AUTHORIZATION env var
    2. OPENCLAW_AUTHORIZATION env var (legacy)
    3. ~/.openclaw/.env (Fallback)
    4. ~/.config/openclaw/hidream_config.json (unified config)
    """
    # 1. Check Env

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common/config.py (reported line 35)May include surrounding context.

python
return token

    # 2. Check ~/.openclaw/.env (Fallback)
    openclaw_env = Path.home() / ".openclaw" / ".env"
    if openclaw_env.exists():
        try:
            with open(openclaw_env, "r") as f:

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script is documented and exposed as a Seedance 1.5 Pro video-generation client, but it constructs a payload for a different backend module/version (hidream-R2-Audio / R2-Audio). This mismatch can cause users or higher-level agents to send prompts, images, and generation parameters to an unintended remote capability, violating user expectations and potentially routing sensitive inputs to the wrong service path or account workflow.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill advertises capabilities that include environment access, file reads/writes, network use, and shell-like credential setup guidance, but it does not declare any explicit tool scope or permissions boundaries. That omission increases the chance an agent will execute higher-risk actions without user-visible consent or policy checks, especially because the instructions include persistent file writes and network operations.

Content

No source excerpt is available for this finding.

Scope Creep

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instructions explicitly tell the agent to write a bearer token into ~/.openclaw/.env, which exceeds the stated read-only media access and introduces persistent secret storage via agent action. This creates a real risk of credential exposure, accidental overwrite of existing config, and unauthorized persistence of sensitive tokens on disk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

Persistently saving generated media in an assets/ directory creates session residue that may outlive the user's intent and remain accessible to later tasks, users, or tools. In a skill that handles remote content and possibly user-supplied prompts/media, this increases privacy and data-retention risk even if the functionality is not overtly malicious.

Content

Scanner excerpt · SKILL.md (reported line 39)May include surrounding context.

md
*   **Interactive**: Run `python3 scripts/configure.py` to interactively save the token.
3.  **Handle Missing Prompts**: If the user asks to generate an image or video but does not provide a specific prompt, **DO NOT generate a random test image**. Instead, politely ask the user what they would like to generate.
4.  **Generate**: Use the Python interface to generate content based on user requests.
5.  **Save Output**: When generation is complete and returns a media URL (image or video), **ALWAYS download and save the file to the `assets/` directory within this skill's folder (e.g., `assets/generated_image.png`)**. Do NOT use `~/.openclaw/workspace/output/` as it may have permission issues. Create the `assets/` directory if it does not exist.
6.  **Present Results**: When showing generated images or videos to the user, **ALWAYS** use the following Markdown formats to ensure proper rendering in the Claw interface. Use the local path if downloaded, or the remote URL:

### Error Handling & Troubleshooting

Scope Creep

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill requires downloading remote media and creating/writing files under assets/, despite earlier framing that file access is limited to reading user-provided media. Undeclared file writes increase the attack surface by enabling persistent storage of potentially unsafe or unexpected content and by normalizing broader filesystem access for the agent.

Content

No source excerpt is available for this finding.

Scope Creep

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code explicitly permits overriding the declared network destination via environment variables, undermining the manifest's stated trust boundary of https://vivago.ai. In a credentialed skill that reads local files and transmits them remotely, this materially increases the risk of silent data and token exfiltration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The function detects local file paths, reads the file contents, base64-encodes them, and later those values can be included in the request payload sent via HTTP. Although there is an inline comment for developers, there is no confirmation prompt, user-facing log, or explicit disclosure to the user in this file that local file contents may be uploaded.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/common/task_client.py (reported line 73)May include surrounding context.

python
endpoint = f"{ENDPOINT}{path}"
    headers = _headers(authorization)
    # print(payload)
    submit_resp = requests.post(endpoint, json=payload, headers=headers, timeout=30)
    if submit_resp.status_code != 200:
        raise RuntimeError(f"http error: {submit_resp.status_code} {submit_resp.text}")
    resp_json = submit_resp.json()

Tainted flow: 'task_id' from requests.post (line 83, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/common/task_client.py (reported line 90)May include surrounding context.

python
result_url = endpoint + "/results"
    start = time.time()
    while True:
        query_resp = requests.get(
            result_url,
            params={"task_id": task_id},
            headers=headers,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This wrapper sends user-supplied prompt and image data to the underlying Kling service via run_kling, which is a network/data-transmission operation. Although the script logs to stderr, those messages are operational and do not clearly disclose to the user that their content will be sent to an external service; there is also no confirmation prompt or explanatory comment/docstring near the action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This is a code file, so missing-warning checks apply. The call to run_task(payload, authorization) transmits user-supplied prompt text, optional image data, request metadata, and possibly credentials, but this file provides no confirmation prompt or explicit disclosure that these inputs will be sent to a remote service.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency specification uses a lower-bound only constraint (requests>=2.25.0), which makes builds non-reproducible and can pull in unexpected versions over time. In a skill that performs authenticated network requests to an external service, this increases supply-chain risk and makes it harder to ensure known-safe dependency versions are installed.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.25.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Because requests is unpinned, it is impossible to verify at install time whether a vulnerable release may be selected, including versions affected by known advisories. This is more concerning here because the skill handles credentials and makes outbound HTTPS requests, so a vulnerable requests version could contribute to credential leakage, request handling flaws, or other client-side security issues depending on the installed release.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code constructs an Authorization header from a provided token and uses it in outbound HTTP requests. While this is expected for API access, this file does not provide any user-facing notice that credentials will be transmitted to the configured endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code accepts image inputs via --images and labels them as image URLs/base64, which implies user-provided data may be sent onward when main(payload, args) executes. The file does not include any confirmation prompt, print/log disclosure, or comment/docstring warning that image data may be transmitted to an external video-generation service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The --images argument help says it accepts "image URLs/base64", but the implementation passes string input to parse_images, and the skill manifest context states the skill reads local image/video files for base64 encoding. This is not just incomplete documentation: it describes a different input model than the code's actual local-file processing behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.