Back to skill

Security audit

Skill Image Gen

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill mostly does what it says, but its setup guidance and code handle API keys and cloud credentials in unsafe ways that users should review before installing.

Install only if you are comfortable sending prompts to Gitee AI and, when enabled, uploading generated images to your Tencent COS bucket. Do not paste real API keys into an AI chat, do not print full keys in logs, and store any Gitee or Tencent credentials with restrictive file permissions or a secret manager. Use a narrowly scoped Tencent key if COS upload is needed, and avoid exposing the helper URL-download function to untrusted URLs without additional network and size limits.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:204
Finding
Credential files are created without enforced restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:204-212` **Vulnerability Type**: Plaintext credential storage with unsafe default permissions **Risk Level**: Medium ### Vulnerable Code ```python # 创建目录 os.makedirs(save_dir, exist_ok=True) # 保存配置 with open(save_path, 'w', encoding='utf-8') as f: json.dump(self._config_data, f, indent=2, ensure_ascii=False) self.config_path = save_path return save_path ``` The configuration object written by this code can contain the Gitee API key, Tencent Cloud SecretId, and Tencent Cloud SecretKey collected elsewhere in the same module. ### Technical Analysis The configuration is persisted as plaintext JSON. Neither the configuration directory nor the file is explicitly assigned owner-only permissions. Consequently, effective permissions depend on the process umask, pre-existing directory permissions, and platform defaults. The same insecure write pattern also occurs when an existing configuration is updated at `scripts/config.py:248-249`: ```python with open(self.config_path, 'w', encoding='utf-8') as f: json.dump(self._config_data, f, indent=2, ensure_ascii=False) ``` Because the configuration may contain long-lived cloud credentials, relying on ambient filesystem defaults does not provide sufficient protection. Existing files with overly broad permissions are not repaired. ### Attack Path 1. A user completes interactive setup and supplies a Gitee API key or Tencent Cloud credentials. 2. The Skill serializes those credentials into `config.json`. 3. The file is created or updated without an explicit owner-only mode. 4. On a system with a permissive umask, shared home directory, insecure backup, or pre-existing broadly readable file, another local account or process reads the configuration. 5. The attacker reuses the exposed credentials against Gitee AI or Tencent Cloud. ### Impact Assessment An attacker may obtain the same remote permissions granted to the exposed credentials. A s ...[truncated 375 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the credential directory with owner-only permissions: ```python os.makedirs(save_dir, mode=0o700, exist_ok=True) os.chmod(save_dir, 0o700) ``` 2. Create configuration files atomically with mode `0600`, for example by using `os.open()` with `O_CREAT | O_EXCL` and an explicit mode. 3. Write to an owner-only temporary file, flush and synchronize it, then atomically replace the destination with `os.replace()`. 4. Explicitly repair permissions on existing configuration files with `os.chmod(path, 0o600)` where supported. 5. Prefer an operating-system credential store or dedicated secret manager rather than plaintext JSON. 6. Recommend temporary, narrowly scoped Tencent Cloud credentials restricted to the required bucket and object operations. 7. Avoid storing credentials when suitable environment variables are already available. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/GET_API_KEY.md:163
Finding
Setup documentation encourages disclosure of complete API keys<![CDATA[ ## Vulnerability Details **File Location**: `references/GET_API_KEY.md:163-172` and `references/GET_API_KEY.md:184-192` **Vulnerability Type**: Unsafe credential handling guidance **Risk Level**: Medium ### Vulnerable Documentation ```text ### 方法二:通过对话配置 如果你使用 OpenClaw 的 AI Agent,可以直接告诉 AI 你的 API Key: 我的 Gitee AI API Key 是:EXXSO8UHNBKI8AHK9TXM5KOILPDUISI25HIKOJ73 AI 会自动帮你更新配置文件。 ``` The guide also recommends printing the complete stored key: ```bash cd <技能目录> python -c "from scripts.config import Config; c = Config(interactive=False); print(f'API Key: {c.get(\"gitee.api_key\")}')" ``` ### Technical Analysis The documentation directs users to place a secret directly into an Agent conversation and verify configuration by printing the full secret to terminal output. Agent conversations may be retained in chat history, telemetry, debugging traces, or execution logs. Terminal output can similarly be captured by shell transcripts, CI logs, support recordings, or orchestration systems. The credential-shaped example also normalizes unsafe secret sharing and could be mistaken for a usable token. A secure verification procedure should confirm only that a credential is present or display a small masked suffix. It should never reproduce the entire value. ### Attack Path 1. A user follows the documented setup procedure. 2. The user submits a real API key through an Agent conversation or runs the command that prints the full key. 3. The secret is retained in conversation history, execution logs, terminal capture, or support material. 4. A party with access to those records retrieves the key. 5. The exposed key is used for unauthorized Gitee AI requests until it is revoked. ### Impact Assessment The attacker can exercise the Gitee AI permissions associated with the exposed key, potentially consuming quotas, generating unauthorized content, or causing account-level service abuse. The issue does not grant local system privileges. Its scope is limited t ...[truncated 83 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove instructions that ask users to provide secrets through Agent conversations. 2. Remove the command that prints the complete API key. 3. Verify configuration by checking only whether the key exists: ```python key = c.get("gitee.api_key") print("API key configured:", bool(key)) ``` 4. If identification is necessary, display only a masked suffix, such as `****OJ73`. 5. Use hidden terminal input through `getpass.getpass()` instead of `input()` so credentials are not echoed. 6. Prefer environment variables, operating-system credential stores, or secret-manager integrations. 7. Replace the credential-shaped example with an unmistakable placeholder such as `YOUR_GITEE_API_KEY`. 8. Advise users to revoke and rotate any key that was previously placed in a conversation or log. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/utils.py:74
Finding
Image download utility permits unrestricted URL fetching and unbounded response processing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils.py:74-96` **Vulnerability Type**: Server-side request forgery and resource exhaustion **Risk Level**: Medium ### Vulnerable Code ```python def download_image(url: str, save_path: str, timeout: int = 30) -> Tuple[str, str]: """ 从 URL 下载图片 Args: url: 图片 URL save_path: 保存目录 timeout: 超时时间 (秒) Returns: (文件名, 完整路径) """ response = requests.get(url, timeout=timeout) response.raise_for_status() # 转换为 base64 再保存 b64_str = base64.b64encode(response.content).decode('utf-8') # 生成文件名 filename = generate_timestamp_filename() full_path = os.path.join(save_path, filename) # 保存 base64_to_image(b64_str, full_path) return filename, full_path ``` ### Technical Analysis `download_image()` accepts an arbitrary URL and passes it directly to `requests.get()`. The implementation does not restrict URL schemes or hosts, reject loopback/private/link-local addresses, or validate redirect destinations. A caller that exposes this function to untrusted URL input could therefore be induced to contact services reachable from the host but inaccessible to an external attacker. The function also accesses `response.content`, buffering the complete response in memory. It then creates another full in-memory Base64 representation before decoding it again. No response-size or image-dimension limit is enforced. This can significantly amplify memory consumption. Finally, untrusted bytes are passed to Pillow. Although Pillow provides decompression-bomb warnings and limits in supported versions, the function does not enforce an application-specific pixel limit or convert such warnings into a controlled rejection. The current command-line entry point does not call this utility, which limits immediate exposure. The risk becomes exploitable when the function is imported by an Agent, web service, or other component with attacker-controlled ...[truncated 1109 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Permit only `https` URLs unless another scheme is explicitly required. 2. Restrict downloads to an allowlist of trusted image hosts where practical. 3. Resolve hostnames and reject loopback, private, reserved, multicast, link-local, and cloud metadata addresses. 4. Disable automatic redirects or validate the destination after every redirect. 5. Stream downloads with `stream=True` and stop when a strict byte limit is exceeded. 6. Validate `Content-Type` and reject non-image responses, while treating it only as an initial check. 7. Remove the unnecessary Base64 round trip and decode from a bounded stream or byte buffer. 8. Set explicit image pixel and dimension limits and reject decompression-bomb warnings. 9. Apply connection and read timeouts separately. 10. Ensure callers do not expose this function to untrusted input unless the network and size controls are enabled. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:4
Finding
Third-party dependencies are not reproducibly pinned<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:4-8` **Vulnerability Type**: Uncontrolled dependency resolution **Risk Level**: Low ### Vulnerable Configuration ```text requests>=2.28.0 Pillow>=9.0.0 # 腾讯云 COS (可选,如需上传到 COS) cos-python-sdk-v5>=1.9.0 ``` ### Technical Analysis All runtime dependencies use lower-bound-only constraints. A new installation can therefore resolve to any future version accepted by the package index. The project provides neither a lock file nor package hashes to verify downloaded artifacts. No malicious or typosquatted package was identified in the reviewed dependency list. The risk arises from the lack of reproducibility and integrity controls: a compromised upstream account, package-index incident, or incompatible future release could alter installation or runtime behavior after this Skill has been reviewed. ### Attack Path 1. A user follows the documented instruction to run `pip install -r requirements.txt`. 2. The package resolver selects versions available at installation time rather than a reviewed dependency set. 3. A compromised, malicious, or unexpectedly incompatible release is downloaded from the configured index. 4. Package installation hooks or imported runtime code execute in the user's environment. 5. The resulting access is limited only by the privileges of the Python installation process and Skill runtime. ### Impact Assessment A malicious dependency can execute code with the privileges of the user installing or running the Skill. Depending on those privileges, it could read local files, access environment variables and stored credentials, modify user-owned data, or communicate over the network. This audit did not identify a currently malicious dependency; therefore, this is a supply-chain hardening issue rather than evidence of an embedded malicious package. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin dependencies to reviewed versions using exact constraints. 2. Generate and commit a lock file suitable for the supported deployment environments. 3. Use package hashes, such as pip's `--require-hashes`, to verify artifact integrity. 4. Install packages only from a documented, trusted index over TLS. 5. Separate optional COS dependencies from the core installation so unused network-capable packages are not installed. 6. Use automated vulnerability scanning and controlled dependency-update reviews. 7. Periodically regenerate locks rather than allowing unrestricted upgrades during user installation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (33)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A description-behavior mismatch is a serious trust and review problem: the skill claims image generation and COS upload, while analysis indicates undeclared arbitrary network download behavior and missing declared core functionality. If true, this could let the skill fetch remote content or process files in ways users and reviewers did not authorize, creating opportunities for data exfiltration, malicious content retrieval, or misleading execution paths.

Missing User Warnings

High
Confidence
99% confidence
Finding
Telling users to provide the API key directly in chat to the AI agent exposes a sensitive credential through a natural-language interface that may be retained, inspected, or forwarded outside the user's local environment. In the context of an image-generation skill, this capability is unnecessary because the key can be configured locally without involving the model.

Ssd 3

High
Confidence
99% confidence
Finding
The documentation creates a direct social-engineering path for users to disclose bearer credentials to an AI system. Because AI platforms commonly store prompts, responses, and diagnostics, this can lead to persistent secret exposure and downstream abuse of the Gitee AI account.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The README explicitly instructs users or agents to collect a Gitee API key, persist it to local configuration, and optionally upload generated images to Tencent COS, but it does not warn that these actions involve sensitive credentials and transmission of user data to third-party services. In an agent context, this omission increases the risk that secrets are solicited or stored insecurely and that users are not meaningfully informed before content is sent to external providers.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documentation describes capabilities that use environment variables, local file reads/writes, and network access, but it does not declare any tool scope or permission boundaries. In an agent setting, missing explicit permissions increases the chance that the skill is granted broader access than users expect, enabling unintended secret access, file modification, or outbound requests.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill advertises cloud upload and local saving but does not clearly warn that prompts, generated images, and related metadata may be transmitted to external providers and stored remotely. Users may unknowingly send sensitive prompts or content to third parties, creating privacy, compliance, and data retention risks.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The configuration guidance instructs users to place API keys and cloud credentials in files and environment variables without explicit secret-handling safeguards. This increases the risk of credential leakage through checked-in config files, permissive file permissions, logs, screenshots, or agent misuse of environment access.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The document warns users not to disclose API keys, then immediately shows a realistic full-length example key and later encourages sharing a key with an AI agent. Even if the example key is not live, this normalizes unsafe handling of secrets and weakens the document's security posture by teaching users that plaintext exposure is acceptable.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Linux/macOS
mkdir -p ~/.openclaw/skills/free-image-gen

# Windows (PowerShell)
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.openclaw\skills\free-image-gen"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Linux/macOS
mkdir -p ~/.openclaw/skills/free-image-gen

# Windows (PowerShell)
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.openclaw\skills\free-image-gen"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The document explicitly instructs users to send their Gitee API key to an AI agent in natural language. That creates an unnecessary credential disclosure path through chat logs, model providers, telemetry, or prompt-history storage, which is especially risky because an API key is a bearer secret that can be reused by whoever obtains it.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# 创建配置目录
mkdir -p ~/.openclaw/skills/free-image-gen

# 创建配置文件
cat > ~/.openclaw/skills/free-image-gen/config.json << 'EOF'
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The module documentation and all user-facing interactive text are written exclusively in Chinese, and the skill provides no indication that users may choose another language or locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code interactively collects API keys and optional COS secrets, then writes them in plaintext JSON to a predictable path under the user's home directory without warning the user about local secret storage, file permissions, or the sensitivity of those credentials. In an agent/tooling context, this increases the chance that other local users, processes, backups, or accidental file disclosure expose long-lived credentials that can be abused for API usage or cloud storage access.

Cloud Storage Exfiltration

Medium
Category
Data Exfiltration
Content
if key is None:
            key = local_path.split('/')[-1].split('\\')[-1]
        
        response = self.client.upload_file(
            Bucket=self.bucket,
            LocalFilePath=local_path,
            Key=key,
Confidence
55% confidence
Finding
Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
This code performs a network upload of a local file to a remote cloud storage service, which can transmit user or system data off the machine. Although the function name and docstring describe uploading, there is no confirmation prompt, user-facing log/print, or explicit warning about this data transfer in the code shown.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The manifest describes a tool for generating images and supporting local save or Tencent COS upload. This module also exposes a delete capability that removes objects from remote cloud storage, which is not mentioned or obviously required by that stated purpose. Deleting remote content is a materially different capability from generating or uploading images.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The delete method performs a destructive remote operation by deleting an object from COS, but it provides no confirmation prompt or advance user disclosure before doing so. A failure message is printed only after the operation errors, which does not warn the user about the irreversible action beforehand.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
When upload_to_cos is enabled, the skill uploads the generated local file to Tencent COS, transmitting user-derived content to a cloud service. The parameter name suggests upload behavior, but this file does not include a clear warning, confirmation, or user-facing disclosure about external cloud transfer.

External Transmission

Medium
Category
Data Exfiltration
Content
"Authorization": f"Bearer {self.api_key}"
        }
        
        response = requests.post(url, json=payload, headers=headers, timeout=60)
        
        if response.status_code != 200:
            raise Exception(f"API 调用失败 ({response.status_code}): {response.text}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This Python file performs a network request to Gitee AI using the user-provided prompt, which may contain sensitive user data. Although the docstrings describe image generation, there is no confirmation prompt, print/log disclosure, or explicit warning in this file that prompt content will be sent to an external service.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
User-facing natural-language strings, including the module description, CLI description, and argument help text, are entirely in Chinese. This imposes a specific language/locale on users without offering any language choice or documenting a justified region-specific constraint.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
All user-facing instructions are provided only in Chinese, and the document does not indicate that this is an optional locale or a region-specific requirement. Under the stated policy, forcing a single language without user opt-in can be a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The entire skill documentation is written in Chinese and does not indicate that other languages are supported or that the language choice is optional. Under the stated policy, forcing a specific language without user opt-in is a natural-language locale violation unless clearly justified as region-specific.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
This requirements file includes natural-language comments entirely in Chinese, such as the header and dependency section labels. Because the file provides no indication that language choice is optional or justified for a region-specific skill, it may violate a language/locale policy requiring user opt-in or neutrality.

Static analysis

No suspicious patterns detected.