Back to skill

Security audit

Image Generator

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill mostly matches its stated purpose, but it has under-disclosed local credential-file access and weak safeguards around downloaded remote content.

Review before installing. Use only with non-sensitive prompts, provide the API key explicitly through the declared environment variable, and be aware that the current script may read local TOOLS.md files and save downloaded content to disk. A safer version should remove ambient credential lookup and restrict downloaded image URLs and file sizes.

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

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/generate.py:17
Finding

Undocumented Access to Workspace Configuration Files

Content
View full analysis
str: """从环境变量或 TOOLS.md 获取 API Key""" # 1. 环境变量 key = os.environ.get("ZHIPU_API_KEY") if key: return key # 2. 从 TOOLS.md 读取 possible_paths = [ Path(__file__).parent.parent.parent.parent / "TOOLS.md", Path.cwd() / "TOOLS.md", Path("~/.openclaw/workspace/TOOLS.md"), ] for path in possible_paths: try: if path.exists(): content = path.read_text(encoding="utf-8") match = re.search(r'ZHIPU_API_KEY:\s*(\S+)', content) if match: key = match.group(1) if key and not key.startswith('请在这里'): return key except Exception: continue return None ``` ### Technical Analysis The skill metadata declares `ZHIPU_API_KEY` as a required environment variable, but the implementation also searches several `TOOLS.md` locations outside the skill directory. This behavior is not disclosed as a required permission or configuration source in the metadata. If the environment variable is absent, the script checks and reads workspace-level files using the privileges of the invoking agent. Such files may contain credentials or unrelated sensitive configuration. Reading broader workspace configuration violates least privilege because image generation only requires access to the explicitly supplied environment variable. The current source does not import the `re` module. Consequently, the regular-expression call raises `NameError`, which is silently suppressed by the broad exception handler. The file is nevertheless opened and read before that exception occurs. The current version therefore performs the undeclared file acces ...[truncated 1626 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate.py:118
Finding

Unvalidated Server-Provided URL Enables Blind SSRF and Unbounded Downloads

Content
View full analysis
str: if not output: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output = f"image_{timestamp}.png" resp = requests.get(url, stream=True, timeout=60) resp.raise_for_status() with open(output, "wb") as f: for chunk in resp.iter_content(chunk_size=8192): if chunk: f.write(chunk) return os.path.abspath(output) ``` The URL reaches this function directly from the API response: ```python data = response.json() if "data" not in data or not data["data"]: print(f"❌ 返回结果中未找到 data 字段或为空: {json.dumps(data, ensure_ascii=False)}") sys.exit(1) first = data["data"][0] image_url = first.get("url") if not image_url: print(f"❌ 返回结果中未找到图片 url: {json.dumps(data, ensure_ascii=False)}") sys.exit(1) print("⬇️ 正在下载图片...") saved_path = download_image(image_url, output) ``` ### Technical Analysis The script treats `data[0].url` from the remote API as trusted and passes it directly to `requests.get()`. It does not validate: - The URL scheme - The destination hostname or resolved IP address - Whether the destination is loopback, private, link-local, or otherwise internal - Redirect destinations - The response content type - The maximum response size - Whether the response is actually an image The `requests` library follows HTTP redirects by default. Validating only an initial URL would therefore be insufficient unless every redirect target is also checked. This creates a blind SSRF primitive if the upstream API, its response path, or an intermediary can cause an arbitrary URL to be returned. The process can t ...[truncated 2225 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented behavior and the analyzed behavior diverge in security-relevant ways: the skill reportedly reads credentials from TOOLS.md beyond the declared environment variable, writes files locally, and does not actually implement the claimed chat-image delivery. This mismatch can mislead users and orchestration systems about what data sources and side effects exist, increasing the risk of credential exposure, unintended file writes, and unsafe automation assumptions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents capabilities that require environment access, filesystem interaction, and outbound network calls, but it does not declare an explicit tool scope such as permissions or allowed-tools. This weakens least-privilege controls and makes it easier for an agent runtime to grant broader access than users expect, especially since the skill handles API credentials and writes downloaded content locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill sends user prompts to an external third-party image generation service and then downloads generated content to local storage, but the description does not clearly warn users about either data transfer or local persistence. This creates a privacy and consent risk because sensitive prompts may leave the environment and downloaded files may remain on disk unexpectedly.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script retrieves ZHIPU_API_KEY not only from the environment but also by searching local TOOLS.md files, which broadens credential access beyond what an image-generation utility needs. This creates unnecessary secret discovery behavior and can silently consume credentials from unrelated workspace files, increasing the risk of unauthorized credential use or accidental exfiltration to the external API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code reads credentials from local TOOLS.md files without any user-facing notice or consent, so the skill may access sensitive local data unexpectedly. In this skill’s context, that is more dangerous because the retrieved key is immediately used to authenticate outbound requests, turning hidden credential access into practical secret use.

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/generate.py (reported line 184)May include surrounding context.

python
try:
        while True:
            response = requests.post(url, json=payload, headers=headers, timeout=120)
            if response.status_code == 429:
                try:
                    err = response.json()

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Most of the operational instructions and examples are presented only in Chinese, which can impose a language constraint on users or operators without an explicit opt-in. The file does not indicate that Chinese is optional or provide an alternative language version.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The argument help text explicitly says the image prompt 'supports Chinese', which introduces a language-specific framing in the user-facing interface. Because there is no accompanying statement that other languages are also accepted or user choice is supported, this can be interpreted as a locale/language policy issue.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.