Back to skill

Security audit

stable Diffusion Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Stable Diffusion WebUI helper, but users should keep its API endpoint trusted because prompts and selected images can be sent there.

Install this only if you intend the agent to use your own trusted Stable Diffusion WebUI. Keep SD_WEBUI_URL on localhost or a trusted HTTPS endpoint, avoid sending sensitive images to remote servers, and be cautious opening generated galleries from directories containing untrusted filenames.

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

T09 · Insecure Skill Coding Practices

Warning
Location
tools/sd_client.py:23
Finding
Unencrypted Transmission of Image Data to an Unrestricted Remote Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `tools/sd_client.py:23-39`, with image data entering outbound requests at `tools/sd_client.py:157-178`, `187-212`, `220-246`, `252-278`, and `283-290` **Vulnerability Type**: Unrestricted remote endpoint configuration and plaintext transmission of sensitive image data **Risk Level**: Medium ### Vulnerable Code ```python SD_WEBUI_URL = os.environ.get("SD_WEBUI_URL", "http://127.0.0.1:7860") SD_TIMEOUT = int(os.environ.get("SD_TIMEOUT", "300")) SD_OUTPUT_DIR = os.environ.get("SD_OUTPUT_DIR", "./sd_output") # ── Helpers ──────────────────────────────────────────────────────────────────── def api_get(endpoint: str) -> dict: url = f"{SD_WEBUI_URL.rstrip('/')}{endpoint}" resp = requests.get(url, timeout=30) resp.raise_for_status() return resp.json() def api_post(endpoint: str, payload: dict) -> dict: url = f"{SD_WEBUI_URL.rstrip('/')}{endpoint}" resp = requests.post(url, json=payload, timeout=SD_TIMEOUT) resp.raise_for_status() return resp.json() ``` For example, `img2img` reads a user-selected local file and includes it in a request to that endpoint: ```python def action_img2img(args): if not args.init_image: print("❌ 需要提供 --init-image 参数") sys.exit(1) payload = { "init_images": [img_to_b64(args.init_image)], "prompt": args.prompt or "", "negative_prompt": args.negative_prompt or "(worst quality:2),(low quality:2),blurry,ugly", "steps": args.steps, "cfg_scale": args.cfg_scale, "width": args.width, "height": args.height, "seed": args.seed, "batch_size": args.batch_size, "denoising_strength": args.denoising_strength, "sampler_name": args.sampler, "resize_mode": args.resize_mode, } print(f"🔄 正在图生图 (强度: {args.denoising_strength})...") result = api_post("/sdapi/v1/img2img", payload) images = result.get("images", []) info = json.loads(resu ...[truncated 3040 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse `SD_WEBUI_URL` with `urllib.parse.urlparse` and reject malformed URLs, embedded credentials, fragments, and unsupported schemes. 2. Permit loopback destinations by default. Require an explicit option such as `--allow-remote-webui` before connecting to non-loopback addresses. 3. Require HTTPS for non-loopback destinations. If plaintext remote HTTP must be supported, require an explicit high-visibility override and warn that images and prompts will be exposed in transit. 4. Disable automatic redirects with `allow_redirects=False`, or validate the scheme and resolved destination of every redirect before following it. 5. Consider resolving hostnames and rejecting loopback, private, link-local, multicast, and cloud metadata addresses when remote access is not part of the intended policy. 6. Display the final destination and the categories of data that will be transmitted before the first remote image request. 7. Add optional authentication support without placing credentials in URLs or logs. 8. Set maximum source-file and response sizes before reading, decoding, or saving image data to reduce resource-exhaustion exposure. 9. Document that Base64 does not encrypt content and that remote deployments must use authenticated TLS. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
tools/image_utils.py:172
Finding
HTML and Attribute Injection in Generated Image Galleries<![CDATA[ ## Vulnerability Details **File Location**: `tools/image_utils.py:172-208` **Vulnerability Type**: HTML injection through unescaped filenames, file paths, and gallery titles **Risk Level**: Medium ### Vulnerable Code ```python def generate_gallery(image_paths: list, output_html: str = "gallery.html", title: str = "SD Generation Gallery"): """Generate a simple HTML gallery from image paths""" images_html = [] for path in image_paths: abs_path = os.path.abspath(path) filename = os.path.basename(path) images_html.append(f''' <div class="card"> <img src="file:///{abs_path.replace(chr(92), "/")}" alt="{filename}"> <div class="caption">{filename}</div> </div>''') html = f"""<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>{title}</title> <style> body {{ font-family: Arial, sans-serif; background: #1a1a2e; color: #eee; margin: 20px; }} h1 {{ color: #e94560; text-align: center; }} .grid {{ display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }} .card {{ background: #16213e; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 16px rgba(0,0,0,0.4); }} .card img {{ width: 100%; height: auto; display: block; }} .caption {{ padding: 8px 12px; font-size: 12px; color: #aaa; word-break: break-all; }} </style> </head> <body> <h1>🎨 {title}</h1> <p style="text-align:center;color:#888">共 {len(image_paths)} 张图像</p> <div class="grid">{''.join(images_html)} </div> </body> </html>""" with open(output_html, "w", encoding="utf-8") as f: f.write(html) print(f"✅ 图库已生成: {os.path.abspath(output_html)}") return output_html ``` ### Technical Analysis The gallery generator directly interpolates the following values into HTML: - `title`, supplied through the `--title` command-line argument - `filename`, derived from every discovered image filename - `abs_path`, inserted into the quoted `src` attribute None ...[truncated 2593 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Escape all untrusted values according to their output context: ```python import html safe_title = html.escape(title, quote=True) safe_filename = html.escape(filename, quote=True) ``` 2. Use `safe_title` in both the `<title>` and `<h1>` elements, and use `safe_filename` in captions and attributes. 3. Do not manually construct file URLs. Use: ```python file_uri = Path(path).resolve().as_uri() safe_file_uri = html.escape(file_uri, quote=True) ``` 4. Prefer a templating engine with automatic escaping enabled rather than assembling HTML with f-strings. 5. Consider copying gallery images into a dedicated output directory under generated safe names instead of embedding arbitrary original paths. 6. Add tests containing filenames and titles with quotes, angle brackets, ampersands, Unicode characters, and attempted event-handler injection. 7. If no scripting is required, add a restrictive Content Security Policy to the generated document, for example: ```html <meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src file: data:; style-src 'unsafe-inline'"> ``` Escaping remains necessary even when a Content Security Policy is present. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tainted flow: 'url' from os.environ.get (line 37, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
# ── Helpers ────────────────────────────────────────────────────────────────────
def api_get(endpoint: str) -> dict:
    url = f"{SD_WEBUI_URL.rstrip('/')}{endpoint}"
    resp = requests.get(url, timeout=30)
    resp.raise_for_status()
    return resp.json()
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 37, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
def api_post(endpoint: str, payload: dict) -> dict:
    url = f"{SD_WEBUI_URL.rstrip('/')}{endpoint}"
    resp = requests.post(url, json=payload, timeout=SD_TIMEOUT)
    resp.raise_for_status()
    return resp.json()
Confidence
90% confidence
Finding
The client POSTs prompts and, in several actions, base64-encoded local image contents to whatever host is specified by SD_WEBUI_URL. If that environment variable is misconfigured or attacker-controlled, sensitive local images and metadata can be exfiltrated to an unintended remote service without any destination validation or user-facing warning.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents a full-featured Stable Diffusion WebUI integration skill for generating and editing images through the SD WebUI API. The supplied code chunk does something much narrower and different: it is a prompt-helper utility. It defines style presets and a Chinese-to-English keyword map, optimizes prompts by appending tags, offers an interactive prompt builder, and prints example command-line usage. There are no HTTP requests, no API client logic, no image processing, no model management, and no implementation of the listed Stable Diffusion features. This is a clear description-behavior mismatch because the actual code's primary purpose and capabilities are materially different from the declared purpose.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
## ⚖️ 免责声明

> **English:**
> This skill is not affiliated with, endorsed by, or connected to AUTOMATIC1111 or the Stable Diffusion project in any way. It is a third-party integration tool that requires users to install SD WebUI independently. The user is solely responsible for ensuring their use of Stable Diffusion complies with applicable laws, terms of service, and licensing requirements. Generated images are subject to users' own responsibility and must comply with all relevant copyright and usage policies.

> **中文:**
> 本 Skill 与 AUTOMATIC1111 或 Stable Diffusion 项目没有任何隶属、认可或关联关系。它是一个第三方集成工具,需要用户自行安装 SD WebUI。用户全权负责确保其使用 Stable Diffusion 符合适用法律、服务条款和许可要求。生成的图片由用户自行承担责任。
Confidence
80% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill performs HTTP requests to an external or configurable API endpoint but reportedly does not declare network capability. Missing permission disclosure is a security and governance issue because users may not realize prompts and images are sent over the network.

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill performs HTTP requests to an external or configurable API endpoint but reportedly does not declare network capability. Missing permission disclosure is a security and governance issue because users may not realize prompts and images are sent over the network.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill does not clearly warn users that prompts and uploaded/reference images will be sent to a local API endpoint and that generated or edited images will be written to disk. This creates a transparency and privacy risk, especially when users may not realize sensitive images, copyrighted material, or private prompts are being persisted or forwarded to another service.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrases are overly broad and may cause the skill to activate on common conversational requests like '画' or '生成一张', even when the user did not intend to use the Stable Diffusion workflow. In a tool-enabled agent, this can lead to unintended prompt transmission, file writes, or image processing actions against the local SD WebUI service.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The module description states the tool performs Chinese-to-English prompt translation, and the user-facing prompts and status messages throughout the file are written in Chinese. Under the policy, forcing a specific language without opt-in is a natural-language policy concern unless the locale restriction is clearly documented and justified as region-specific, which is not done here.

External Transmission

Medium
Category
Data Exfiltration
Content
def api_post(endpoint: str, payload: dict) -> dict:
    url = f"{SD_WEBUI_URL.rstrip('/')}{endpoint}"
    resp = requests.post(url, json=payload, timeout=SD_TIMEOUT)
    resp.raise_for_status()
    return resp.json()
Confidence
83% confidence
Finding
The tool transmits prompts, configuration, and sometimes encoded local image content via HTTP POST to the configured API endpoint. External transmission is expected for this integration, but it still presents confidentiality risk when the endpoint is remote, untrusted, or uses insecure transport.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Several actions send user-supplied local images to the configured WebUI API, yet the tool gives no explicit notice that local files are being transmitted to a potentially remote service. In this skill context, users may assume a local-only workflow because the default URL is localhost, making silent remote transfer more dangerous if configuration changes.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
User-visible strings throughout the script are in Chinese, such as the success output here, with no option to select another language or indication that the tool is intentionally region-specific. That creates a natural-language locale policy issue under the rule requiring user choice or clear justification for locale constraints.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The manifest describes a Stable Diffusion WebUI integration for generating images, editing them, applying styles, using ControlNet, and managing SD models. This file also implements image analysis capabilities via `/sdapi/v1/interrogate` and extraction of embedded generation metadata via `/sdapi/v1/png-info`, which are not mentioned in the manifest description and are semantically distinct from generation/editing operations.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The generated HTML sets `lang="zh"` and includes Chinese-only visible text such as `共 ... 张图像`, which imposes a specific language/locale in the user-facing output without any opt-in or choice. This is a natural-language policy issue because the skill produces localized content regardless of user preference.

Description-Behavior Mismatch

Low
Confidence
77% confidence
Finding
The manifest focuses on creating and editing images and managing models, but this code also exposes operational control over running backend jobs through `/sdapi/v1/skip` and `/sdapi/v1/interrupt`. While related to Stable Diffusion operation, these are control-plane capabilities not reflected in the stated description.

Static analysis

No suspicious patterns detected.