Back to skill

Security audit

seedream(doubao)-image-generation

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its image-generation purpose, but it can send API credentials and selected image data to an arbitrary configured endpoint and can expose input images in logs or returned output.

Review before installing. Use this only in an environment where SEEDREAM_BASE_URL is controlled and points to a trusted HTTPS Volcengine endpoint, and avoid sending sensitive images because selected image files are uploaded and may be printed back in logs/output. Prefer sandboxed download paths and avoid enabling unrelated tools such as web_search unless you understand the API behavior.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/seedream.js:143
Finding

Unrestricted API Endpoint Override Can Exfiltrate Credentials and Image Data in JavaScript

Content
View full analysis
' : undefined } })); const dataString = JSON.stringify(payload); const options = { hostname: parsedUrl.hostname, port: parsedUrl.port || 443, path: parsedUrl.pathname + parsedUrl.search, method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(dataString) } }; ``` ### Technical Analysis The destination of the authenticated API request is taken directly from the `SEEDREAM_BASE_URL` environment variable. The code does not verify that the destination belongs to Volcengine or another explicitly trusted host before adding the `SEEDREAM_API_KEY` bearer credential. The request payload can also contain the user's prompt and complete base64-encoded contents of every local image supplied through the `image` parameter. Consequently, an untrusted endpoint receives both authentication material and potentially private input data. Although the JavaScript implementation uses `https.request`, which establishes TLS, TLS only protects the connection to the selected host. It does not establish that the selected host is authorized to receive the Seedream credential or image data. ### Attack Path 1. An attacker influences process configuration, a launcher, CI environment, deployment man ...[truncated 1093 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/seedream.py:66
Finding

Unrestricted API Endpoint Override Can Exfiltrate Credentials and Image Data in Python

Content
View full analysis
" if k.lower() == "authorization" else v) for k, v in headers.items()}, "payload": {**payload, "image": "" if "image" in payload else None} }, ensure_ascii=False)) req = urllib.request.Request( url, data=json.dumps(payload).encode("utf-8"), headers=headers, method="POST" ) ``` ### Technical Analysis The Python implementation accepts the request URL directly from `SEEDREAM_BASE_URL` and sends the Seedream bearer credential to that destination without validating its scheme, hostname, or port. Unlike the JavaScript implementation, Python's `urllib.request` can process an HTTP URL. Therefore, a configured `http://` endpoint may transmit the API key, prompt, and base64 image contents without transport encryption. An attacker-controlled HTTPS endpoint is also dangerous because the absence of host authorization allows valid TLS to terminate at an unauthorized recipient. ### Attack Path 1. An attacker modifies or influences `SEEDREAM_BASE_URL` in the process environment. 2. The environment variable is set to an attacker-controlled HTTP or HTTPS endpoint. 3. A user invokes ...[truncated 897 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/seedream.js:172
Finding

Base64-Encoded Input Images Are Returned and Logged by the JavaScript Implementation

Content
View full analysis
{ try { const resJson = JSON.parse(resData); console.log('[seedream] response:', JSON.stringify(resJson)); if (resJson.data) { resJson.input_params = payload; if (params.download_dir) { const saveDir = params.download_dir; if (!fs.existsSync(saveDir)) { fs.mkdirSync(saveDir, { recursive: true }); } for (let i = 0; i < resJson.data.length; i++) { const item = resJson.data[i]; if (item.url) { try { const ext = payload.output_format === 'png' ? '.png' : '.jpeg'; const filename = `image_${resJson.created || Date.now()}_${i}${ext}`; const destPath = path.join(saveDir, filename); await downloadImage(item.url, destPath); item.local_path = destPath; } catch (err) { item.local_path_error = err; } } } } } console.log('[seedream] output:', JSON.stringify(resJson)); resolve(resJson); } catch (e) { const result = { error: "Parse error", message: resData }; console.error('[seedream] error:', JSON.stringify(result)); resolve(result); } }); ``` The CLI subsequently prints the returned object again: ```javascript generateImage(params).then(res => console.log(JSON.stringify(res, null, 2))); ``` ### Technical Analysis For image-to-image requests, `payload.image` contains one or more complete base64 da ...[truncated 1721 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/seedream.py:150
Finding

Base64-Encoded Input Images Are Returned and Logged by the Python Implementation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tainted flow: 'req' from os.environ.get (line 150, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The request destination is derived from the SEEDREAM_BASE_URL environment variable and then used in urllib.request.urlopen without validation. In this skill, the request carries the Bearer API key in the Authorization header and may also include base64-encoded local image contents, so a tampered environment can redirect secrets and local file data to an attacker-controlled endpoint.

Content

Scanner excerpt · scripts/seedream.py (reported line 154)May include surrounding context.

python
input_params_for_return = payload

    try:
        with urllib.request.urlopen(req) as response:
            res_json = json.loads(response.read().decode("utf-8"))
            print("[seedream] response:", json.dumps(res_json, ensure_ascii=False))

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- If your runtime is primarily Node.js/TypeScript or a web module, use **scripts/seedream.js**.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares required environment variables and clearly depends on outbound network access, but the manifest does not declare an explicit tool scope such as permissions or allowed-tools. This creates ambiguity about what the skill is permitted to access and makes review and enforcement harder, increasing the chance of overbroad execution in host environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states that local image files are read, base64-encoded, and transmitted to a remote API, but it does not warn about privacy, confidentiality, or sensitive metadata implications. Users may unknowingly upload private images or regulated content to a third-party service, causing data leakage or compliance issues.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The documentation introduces a tools parameter with an example enabling web_search, which is outside the stated purpose of image generation. Expanding a skill's scope to include external search increases attack surface, may trigger unintended data flow to third parties, and can mislead operators about what the skill actually does.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The usage example actively advertises passing tools '[{"type": "web_search"}]', normalizing use of a capability unrelated to the skill's declared image-generation function. Examples strongly influence real usage, so this can lead users to invoke unnecessary external access and broaden the data exposure surface.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code forwards an arbitrary tools array to the remote model API, including generic capabilities such as web_search, even though the skill is presented as an image-generation tool. That expands the effective capability surface beyond the declared purpose and may let prompts trigger external data access or other tool-mediated behavior not expected by users or orchestrators.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill allows callers to supply an arbitrary download_dir and will create directories and write downloaded files there, but the skill description does not disclose this filesystem write capability. In an agent context, that hidden side effect can be abused to place files in sensitive or unexpected locations, especially if higher-level policy assumes the skill is only performing remote image generation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The documentation URLs explicitly include lang=zh, which steers users to Chinese-language materials. Because the skill does not offer an alternative language option or explain that the documentation is intentionally Chinese-only, this may violate the language/locale policy.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.