Back to skill

Security audit

Ernie Image Radeon

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is coherent and disclosed, but it defaults to sending prompts over unauthenticated HTTP and includes unsafe optional download and installer guidance that users should review carefully.

Install only if you are comfortable sending non-sensitive prompts to the default AMD Radeon Cloud HTTP endpoint. Prefer configuring a trusted HTTPS `ERNIE_BASE_URL`, avoid `--format url` unless you trust the provider response path, and do not run the documented `curl | sh` installer without separately verifying the installer source.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
references/api-guide.md:182
Finding

Unverified Remote Installer Executed Directly by a Shell

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate.py:31
Finding

Image Prompts and API Responses Use an Unauthenticated Plaintext HTTP Channel

Content
View full analysis
object: base_url = os.environ.get("ERNIE_BASE_URL", "").strip() or RADEON_BASE_URL api_key = os.environ.get("AI_STUDIO_API_KEY", "").strip() # Suppress API key for plaintext HTTP endpoints to avoid credential leakage. # Key is only forwarded when the endpoint uses HTTPS (a trusted endpoint). if api_key and base_url.startswith("http://"): print( "Warning: AI_STUDIO_API_KEY is set but the endpoint uses HTTP. " "Key will NOT be sent over plaintext. Use an HTTPS endpoint " "(ERNIE_BASE_URL) to enable authentication.", file=sys.stderr, ) api_key = "" if not api_key: api_key = "radeon-cloud" timeout = OPENAI_TIMEOUT_SECONDS timeout_str = os.environ.get("ERNIE_TIMEOUT", "").strip() if timeout_str: try: timeout = float(timeout_str) except ValueError: pass client = OpenAI( api_key=api_key, base_url=base_url, timeout=timeout, ) extra_body = build_extra_body(args) try: return client.images.generate( model=args.model, prompt=args.prompt, n=args.n, size=args.size, response_format=args.response_format, extra_body=extra_body if extra_body else None, ) ``` ### Technical Analysis The default API endpoint uses HTTP rather than HTTPS and is identified by a raw IP address. Consequently, the connection provides neither transport confidentiality nor authenticated server identity. The code correctly suppresses `AI_STUDIO_API_KEY` when the endpoint begins with `http://`, which ...[truncated 2057 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate.py:265
Finding

Unrestricted and Unbounded Download of API-Provided URLs

Content
View full analysis
None: """Download an image from *url* to *filepath* with timeout checks.""" parsed = urlparse(url) if parsed.scheme not in ("http", "https"): raise ValueError(f"Image URL must use http or https, got {parsed.scheme}") request = urllib.request.Request( url, headers={"User-Agent": "ernie-image-radeon/1.0"}, ) try: with urllib.request.urlopen(request, timeout=DOWNLOAD_TIMEOUT_SECONDS) as response: filepath.write_bytes(response.read()) except URLError as exc: raise RuntimeError(f"Could not download image URL: {exc}") from exc ``` ### Technical Analysis When `--format url` is selected, the URL returned by the remote generation service is passed to `urllib.request.urlopen`. Validation only confirms that the initial scheme is HTTP or HTTPS. The function does not: - Restrict downloads to trusted hosts. - Require HTTPS. - Reject loopback, private, link-local, multicast, or reserved IP ranges. - Revalidate the destination after DNS resolution. - Validate each redirect target. - Limit the maximum response size. - Stream the response with a bounded byte count. - Validate the HTTP status, content type, or decoded image format. The timeout limits elapsed waiting behavior but does not impose a content-size limit. `response.read()` loads the complete response into memory before `write_bytes` writes it to disk. Because the API controls the URL, compromise of the service can exploit this behavior. The plaintext default API channel also allows a network-positioned attacker to potentially substitute an arbitrary URL in the response. ### Attack Path #### Internal Network Request Path 1. The user invokes the sc ...[truncated 1862 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill explicitly instructs the agent to access environment variables, write local files, and make network requests, but it does not declare any tool scope or allowed-tools boundary. This creates a permission mismatch: an agent platform may expose more capabilities than users expect, increasing the risk of silent data exfiltration or unintended file writes, especially since the default endpoint uses unencrypted HTTP.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger list includes very broad phrases like "draw" and "generate image," and the skill says to "generate immediately with defaults." In a conversational agent, this can cause accidental invocation from ordinary user speech, leading to unintended network transmission of user text to a third-party service and local file creation without clear confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script defaults to a plaintext HTTP endpoint (RADEON_BASE_URL = "http://134.199.132.159/ocr/v1") and sends user prompts to it during image generation. This exposes prompt contents to interception or modification in transit by network attackers, which is especially relevant because prompts may contain sensitive user data and the endpoint could be tampered with via man-in-the-middle attacks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The description says "Chinese prompts excel" and that the skill "specializes in Chinese" styles, which introduces a language preference in the natural-language guidance. While not a hard prohibition, this can steer behavior toward a specific language without stating that language choice remains up to the user.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The section titled 'Chinese Prompt Tips' states that Chinese prompts often produce better results and then recommends Chinese-specific subjects and themes. This creates a language preference in the guidance without offering an explicit user choice or documenting a necessary region-specific constraint.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The guide instructs users to pipe a remote script directly into a shell via curl | sh, which is a classic supply-chain and remote-code-execution risk. If the hosting site, transport, DNS, or published installer is compromised, users could execute attacker-controlled code immediately on their system.

Content

Scanner excerpt · references/api-guide.md (reported line 182)May include surrounding context.

md
| Empty response | Temporary API issue | Retry after a few seconds |
| Invalid size | Size not in allowed list | Use one of the 7 supported sizes |
| Invalid prefix | Unsafe filename prefix | Use letters, numbers, `_`, `-`, or `.` |
| `uv run` fails | uv not installed or Python < 3.11 | Install uv: `curl -LsSf https://astral.sh/uv/install.sh \| sh` |

---