Back to skill

Security audit

Hana Image Gen MacOS

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is mostly purpose-aligned, but it needs review because its helper can fetch and save arbitrary URLs returned by a model before sending output.

Review before installing. Use it only if you are comfortable sending prompts to OpenRouter and generated media/captions through Telegram. Avoid sensitive prompts, and prefer a version that allowlists image provider URLs, blocks internal/private destinations, verifies image content and size, and clearly documents token and file handling.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gen.py:35
Finding

Unrestricted Download of Model-Provided URLs Enables Server-Side Request Forgery

Content
View full analysis
str: parsed = urlparse(url) ext = os.path.splitext(parsed.path)[1].lstrip(".") or "png" filename = f"openrouter_image_{int(time.time())}_{idx}.{ext}" path = os.path.join(out_dir, filename) r = requests.get(url, timeout=60) r.raise_for_status() with open(path, "wb") as f: f.write(r.content) return path ``` URLs are collected from multiple fields in the remote model response, including arbitrary URLs embedded in textual content: ```python elif isinstance(content, str): if "data:image/" in content: for token in content.split(): if token.startswith("data:image/"): urls.append(token) if "http://" in content or "https://" in content: for token in content.split(): if token.startswith("http://") or token.startswith("https://"): urls.append(token) ``` Every extracted non-data URL is then downloaded: ```python paths = [] for i, u in enumerate(urls): if u.startswith("data:image/"): paths.append(_save_data_url(u, out_dir, i)) else: paths.append(_download_url(u, out_dir, i)) return paths ``` ### Technical Analysis The script treats URLs supplied by the OpenRouter/model response as trusted and passes them directly to `requests.get()`. It does not enforce HTTPS, restrict destinations to approved image-hosting domains, validate resolved IP addresses, or reject loopback, private, link-local, reserved, and cloud metadata address ranges. Redirect destinations are also not validated. Consequently, a malicious or prompt-influenced model response containing a URL such as ...[truncated 3047 chars]
Remediation
View remediation
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
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior does not match the effective behavior described by analysis: it can write files locally, make outbound requests to arbitrary image URLs returned by an API, and lacks the claimed safeguards or delivery flow. This mismatch is dangerous because reviewers and operators may approve the skill under false assumptions, while it actually expands the attack surface to untrusted remote content and undeclared filesystem activity.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · _meta.json (reported line 5)May include surrounding context.

json
{
  "name": "Hana Image Gen MacOS",
  "slug": "hana-image-gen-macos",
  "version": "1.0.0",
  "description": "MacOS Gemini image gen skill for OpenClaw agents. Auto gen & send to Telegram.",
  "tags": ["image", "ai", "gemini", "macos", "openrouter"],
  "author": "@eardori",
  "license": "MIT"
}

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes a Python script with access to environment variables and external network resources, but it declares no explicit tool scope or permissions. This increases the chance that an agent or runtime will execute the skill with broader capabilities than users expect, including access to secrets like API keys and the ability to make outbound requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description states the skill will do image generation for OpenClaw agents but provides no explicit trigger phrases, activation constraints, or exclusion conditions. This makes it unclear when the skill should activate versus when a general image-related request should be handled another way.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The markdown does not warn that user prompts are sent to an external image-generation service, which can expose sensitive or regulated data if users include confidential content. In this context, the risk is elevated because prompts may originate from agent workflows where users do not realize their input leaves the local environment.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description says the skill will 'Auto gen & send to Telegram' but does not specify the activation conditions, scope, or any exclusions. In a manifest file, this kind of broad capability description can contribute to ambiguous invocation behavior because it does not clarify when the skill should run versus when it should not.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code blindly downloads any URL returned by the model output and writes the response body to disk without restricting host, scheme, content type, size, or redirect behavior. Because model output is untrusted, this turns an image-generation helper into a generic network fetch primitive that can be abused for SSRF-like access, unexpected external requests, disk writes, and retrieval of non-image content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code sends the user-provided prompt to an external OpenRouter API and includes a bearer API key in the request headers, but there is no print statement, prompt, docstring, or comment disclosing that user input is transmitted off-system. For a code file, outbound network transmission of user or system data should have some visible user disclosure unless clearly documented elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The script downloads remote image content and writes it into /tmp, and also writes decoded data URLs to disk, but the code provides no visible notice beyond the final JSON output. File writes are safety-relevant operations under this rule when there is no confirmation, logging, or explanatory comment/docstring.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The manifest only describes image generation via OpenRouter and does not mention credential access. Reading OPENROUTER_API_KEY from the environment is a sensitive capability that may be common for implementation, but it is not justified by the manifest text alone.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.