Back to skill

Security audit

comfyui-running

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with ComfyUI image generation, but it uses high-impact local automation with weak scoping and consent controls.

Review before installing. Use this only if you are comfortable letting the skill start ComfyUI, install Python packages if dependencies are missing, control a Chrome/Edge debugging session, write generated images to your ComfyUI output folder, and potentially clear pending ComfyUI jobs. Prefer running it in an isolated environment, change ComfyUI startup to bind to 127.0.0.1, avoid sharing the ComfyUI queue with other users, and verify any browser debugging tab is only the intended ComfyUI page.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
lib/comfyui_automation.py:256
Finding
ComfyUI Service Is Exposed on All Network Interfaces Without Access Controls<![CDATA[ ## Vulnerability Details **File Location**: `lib/comfyui_automation.py`, lines 256-260 **Vulnerability Type**: Unnecessary network exposure and missing access controls **Risk Level**: High ### Vulnerable Code ```python cmd = [ python_exe, main_py, "--listen", "0.0.0.0", "--port", str(self.port) ] ``` ### Technical Analysis The automation launches ComfyUI with `--listen 0.0.0.0`, which binds the service to every available network interface. This is unnecessary because the skill's own API operations use `http://127.0.0.1:<port>`. The skill does not add authentication, authorization, transport encryption, or source-address restrictions. The actual exposure also depends on the host firewall and ComfyUI configuration, but the launch command makes remote access possible by default. ComfyUI installations can include custom nodes with extensive filesystem, network, model-loading, or command-execution capabilities. Exposing such an instance increases the consequences of any weakness in ComfyUI or an installed custom node. ### Attack Path 1. A user invokes image generation while ComfyUI is not already running. 2. `ensure_comfyui_running()` calls `start_comfyui()`. 3. `_build_start_command()` adds `--listen 0.0.0.0`. 4. ComfyUI begins listening on every network interface at the configured port. 5. A host with network access connects to the exposed ComfyUI API. 6. The remote host may inspect API data, submit workflows, consume system resources, or reach capabilities exposed by installed custom nodes. ### Impact Assessment An attacker able to reach the port may obtain unauthorized access to the ComfyUI API and its workflow-processing capabilities. Potential effects include disclosure of workflow history, unauthorized generation jobs, GPU or CPU resource exhaustion, access to generated content, and abuse of installed custom nodes. The scope is the ComfyUI process and any files, devices, network resources, or custom-node capabilities access ...[truncated 44 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Bind to `127.0.0.1` by default: ```python cmd = [ python_exe, main_py, "--listen", "127.0.0.1", "--port", str(self.port) ] ``` - Require an explicit configuration option and prominent confirmation before enabling remote access. - If remote access is necessary, place ComfyUI behind an authenticated reverse proxy with TLS. - Restrict inbound access using host and network firewalls. - Run ComfyUI under a dedicated, least-privileged operating-system account. - Audit installed custom nodes before allowing any remote connectivity. ]]>

T08 · Insecure Dependencies

Warning
Location
lib/comfyui_automation.py:901
Finding
Unpinned Python Dependencies Are Installed Automatically at Runtime<![CDATA[ ## Vulnerability Details **File Location**: `lib/comfyui_automation.py`, lines 901-906 **Vulnerability Type**: Unsafe runtime dependency installation **Risk Level**: Medium ### Vulnerable Code ```python for pkg, mod_name in [('requests', 'requests'), ('websockets', 'websockets')]: try: importlib.import_module(mod_name) except ImportError: print(f"[INFO] Installing dependency: {pkg}") subprocess.check_call([sys.executable, "-m", "pip", "install", pkg, "-q"]) ``` The documentation also recommends unpinned installation in `SKILL.md`, lines 151-154: ```bash pip install requests websockets ``` ### Technical Analysis `quick_generate()` calls `_ensure_dependencies()`, which installs missing packages from the configured Python package index during ordinary execution. No versions or artifact hashes are specified. Python package installation can execute package build and installation logic. Consequently, the effective code executed by the skill is not fully represented by the audited project: it can change according to the package index, index configuration, dependency resolution, or package releases available when the skill runs. The packages named here are legitimate and no dependency-confusion package name was identified. The risk arises from automatic, unpinned installation and the lack of reproducible integrity verification. ### Attack Path 1. A user invokes `quick_generate()` in an environment where `requests` or `websockets` is absent. 2. `_ensure_dependencies()` catches `ImportError`. 3. The function runs `python -m pip install <package> -q`. 4. Pip resolves an unspecified version from the active package index or mirror. 5. Downloaded package installation code executes with the permissions of the skill process. 6. A compromised index, malicious mirror, or compromised future release could execute unauthorized code. ### Impact Assessment Dependency installation runs with the current user's privileges and may modi ...[truncated 292 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove dependency installation from `quick_generate()` and all normal runtime paths. - Declare dependencies in a standard packaging manifest or requirements file. - Pin reviewed versions, for example with exact `==` constraints. - Use a lock file and verify package hashes with `--require-hashes`. - Perform installation only during an explicit setup step after user confirmation. - Use an isolated virtual environment rather than modifying a shared interpreter. - Configure trusted package indexes explicitly and apply dependency vulnerability scanning. - Report a clear missing-dependency error instead of silently installing software. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
comfyui_browser.py:79
Finding
Caller-Supplied CDP Tab IDs Permit Control of Unrelated Browser Pages<![CDATA[ ## Vulnerability Details **File Location**: `comfyui_browser.py`, lines 79-80 and 667-695 **Vulnerability Type**: Missing target-origin validation in browser automation **Risk Level**: High ### Vulnerable Code ```python def get_ws_url(tab_id, debug_port=DEBUG_PORT): return f"ws://127.0.0.1:{debug_port}/devtools/page/{tab_id}" ``` The caller-provided identifier is used directly: ```python tab_id = sys.argv[1] # sys.argv[1] = TAB_ID real_action = sys.argv[2] # sys.argv[2] = ACTION real_arg = sys.argv[3] if len(sys.argv) > 3 else None # sys.argv[3] = arg ws_url = get_ws_url(tab_id) try: ws = await ws_connect_with_retry(ws_url) async with ws: if real_action == "screenshot": path = real_arg or "/tmp/comfyui.png" ok = await screenshot(ws, path) print(f"{'OK' if ok else 'FAILED'}: {path}") elif real_action == "press_key": ok = await press_key(ws, real_arg or "Enter") print(f"Key sent: {real_arg}") elif real_action == "set_batch": count = int(real_arg) if real_arg else 2 ok, detail = await set_batch(ws, count) print(f"Batch {'OK' if ok else 'FAILED'}: {detail}") ``` ### Technical Analysis The script accepts an arbitrary Chrome DevTools Protocol page identifier and constructs a WebSocket URL without verifying that the target page belongs to the configured ComfyUI origin. Although `find_comfyui_tab()` searches for a ComfyUI page, the general command dispatcher does not require callers to use that result and does not repeat the origin check. CDP grants powerful access to the selected browser target. The implemented actions include screenshot capture, keyboard injection, mouse interaction, and fixed JavaScript execution. This crosses the legitimate privilege boundary of a ComfyUI automation skill because an unrelated page in the same debugging session may contain private or authenticated content. ### Attack Path 1. Chr ...[truncated 995 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not accept an unchecked browser tab ID from the caller. - Query the CDP target list internally and select only a target whose parsed origin exactly equals the configured ComfyUI origin. - Before every connection, map the supplied ID back to its target metadata and reject non-ComfyUI URLs. - Avoid substring checks; compare the scheme, hostname, and configured port explicitly. - Use a dedicated browser instance and isolated profile containing only the ComfyUI page. - Limit the action dispatcher to operations required for ComfyUI. - Disable screenshot and generic key-input actions unless explicitly needed and authorized. - Document that the CDP port must remain loopback-only and inaccessible to other users or hosts. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
comfyui_browser.py:407
Finding
Workflow Execution Deletes All Pending ComfyUI Queue Entries<![CDATA[ ## Vulnerability Details **File Location**: `comfyui_browser.py`, lines 407-425 **Vulnerability Type**: Destructive cross-workflow queue operation **Risk Level**: Medium ### Vulnerable Code ```python def clear_queue(): """清空当前队列(删除 pending 状态的条目)""" try: # 获取队列 url = f"http://127.0.0.1:{COMFYUI_PORT}/queue" resp = urllib.request.urlopen(url, timeout=5) queue_data = json.loads(resp.read()) # 删除队列中的项目 for item in queue_data.get("queue_pending", []): prompt_id = item.get("prompt_id") if prompt_id: try: del_url = f"http://127.0.0.1:{COMFYUI_PORT}/queue/pending/{prompt_id}" req = urllib.request.Request(del_url, method="DELETE") urllib.request.urlopen(req, timeout=5) print(f"Cleared stale queue entry: {prompt_id[:20]}") except: pass except Exception as e: print(f"Queue clear warning: {e}", file=sys.stderr) ``` The function is invoked automatically from `api_run_workflow()` at line 443: ```python # 清空陈旧队列条目 clear_queue() ``` ### Technical Analysis The function describes queue entries as stale but performs no age, owner, session, workflow, or prompt-ID validation. It enumerates the entire pending queue and sends a deletion request for every entry. Because `api_run_workflow()` invokes `clear_queue()` automatically, destructive behavior occurs during routine workflow submission rather than through a narrowly scoped, explicit cancellation operation. ComfyUI queues may be shared by multiple users, automation processes, or workflows. The skill has no reliable basis for treating all existing pending jobs as its own. ### Attack Path 1. A ComfyUI instance contains pending jobs submitted by another user or process. 2. A user invokes the skill's `api_run` or workflow execution path. 3. `api_run_workflow()` calls `clear_queue()` before subm ...[truncated 590 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the unconditional `clear_queue()` call from `api_run_workflow()`. - Record prompt IDs submitted by the current process and cancel only those IDs. - Require explicit user confirmation before any queue cancellation. - If cleanup is necessary, define and enforce a documented age threshold and ownership mechanism. - Do not infer ownership from workflow names or image filename prefixes. - Return queue conflicts to the caller rather than deleting unrelated work. - Replace broad exception suppression with explicit error reporting and audit logging. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
config.json:1
Finding
Commented Configuration Is Invalid JSON and Security-Relevant Settings Are Silently Ignored<![CDATA[ ## Vulnerability Details **File Location**: `config.json`, lines 1-4; `lib/comfyui_config.py`, lines 69-86 **Vulnerability Type**: Fail-open configuration parsing **Risk Level**: Low ### Vulnerable Code The shipped file uses JavaScript-style comments, which standard JSON does not support: ```json { // ============================================================================= // ComfyUI Running Skill - 配置文件 // ============================================================================= ``` The loader uses the standard JSON parser and silently falls back to an empty configuration: ```python def _load_config(): """加载 config.json""" config_path = _get_config_path() if os.path.exists(config_path): try: with open(config_path, "r", encoding="utf-8") as f: return json.load(f) except (json.JSONDecodeError, UnicodeDecodeError): # 尝试 UTF-8-BOM 编码(部分 Windows 文件) try: with open(config_path, "r", encoding="utf-8-sig") as f: return json.load(f) except Exception: return {} return {} ``` ### Technical Analysis Python's `json.load()` rejects `//` comments. Therefore, the provided `config.json` cannot be parsed by either the UTF-8 or UTF-8-BOM attempt. The nested exception handler then returns `{}` without notifying the caller. As a result, security-relevant configuration values—including ports, executable paths, browser settings, and output locations—may not be applied. The program instead uses environment variables, auto-detection, and defaults. Silent failure makes actual runtime behavior differ from the user's reviewed configuration. ### Attack Path 1. The skill loads the shipped or similarly commented `config.json`. 2. `json.load()` raises `JSONDecodeError`. 3. The UTF-8-BOM retry encounters the same unsupported comments. 4. The broad exception handler returns an empty dictionary. 5. The program silen ...[truncated 616 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Ship strict, valid JSON without comments. - Alternatively, use a format that officially supports comments, such as TOML, and parse it with the corresponding validated parser. - Treat malformed configuration as a visible startup error instead of returning an empty dictionary. - Include the configuration filename and parse location in the error message. - Validate the loaded configuration against a schema, including port ranges, path types, allowed UI values, and browser types. - Display the effective configuration before launching ComfyUI when defaults or auto-detected values are used. - Add automated tests that parse the exact configuration file included in the release package. ]]>
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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (40)

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

Critical
Category
Data Flow
Content
"""
    try:
        url = f"http://127.0.0.1:{port}/system_stats"
        r = requests.get(url, timeout=timeout)
        if r.status_code == 200:
            data = r.json()
            version = data.get("system", {}).get("comfyui_version", "")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Claiming cross-platform REST workflow execution while actually probing local Windows/WSL/Linux installation paths and performing filesystem diagnostics creates a transparency and trust problem. In a skill ecosystem, hidden or under-declared host inspection can expose sensitive directory structure information and expands the attack surface beyond the user's expected workflow operation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Claiming cross-platform REST workflow execution while actually probing local Windows/WSL/Linux installation paths and performing filesystem diagnostics creates a transparency and trust problem. In a skill ecosystem, hidden or under-declared host inspection can expose sensitive directory structure information and expands the attack surface beyond the user's expected workflow operation.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
import json, asyncio, websockets, base64, sys, urllib.request, os, time, random

# 清除所有代理环境变量
for k in list(os.environ.keys()):
    if 'proxy' in k.lower():
        del os.environ[k]
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
import json, asyncio, websockets, base64, sys, urllib.request, os, time, random

# 清除所有代理环境变量
for k in list(os.environ.keys()):
    if 'proxy' in k.lower():
        del os.environ[k]
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
# 深拷贝避免修改原数据
                            import copy
                            prompt_copy = copy.deepcopy(nodes)
                            return prompt_copy, history_id
    except Exception as e:
        print(f"Error getting history: {e}", file=sys.stderr)
    return None, None
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
startupinfo=startupinfo,
                        stdout=subprocess.DEVNULL,
                        stderr=subprocess.DEVNULL,
                        env=os.environ.copy()
                    )
                except PermissionError:
                    # PermissionError: 尝试使用系统 Python
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
startupinfo=startupinfo,
                        stdout=subprocess.DEVNULL,
                        stderr=subprocess.DEVNULL,
                        env=os.environ.copy()
                    )
                except PermissionError:
                    # PermissionError: 尝试使用系统 Python
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
startupinfo=startupinfo,
                        stdout=subprocess.DEVNULL,
                        stderr=subprocess.DEVNULL,
                        env=os.environ.copy()
                    )
                except PermissionError:
                    # PermissionError: 尝试使用系统 Python
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
Dynamic software installation via pip is an unjustified privileged action for this skill's primary function. Even if the package names are fixed, it permits unreviewed code retrieval and environment mutation at execution time, which is dangerous in agent contexts.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The documented trigger phrase is a normal-language request ('帮我启动ComfyUI并生成一张猫咪图片') that overlaps with ordinary user intent, so the skill may activate in situations where the user did not explicitly consent to this specific automation package. In this skill’s context, activation can cascade into process launch, workflow execution, dependency installation, and file download, making broad triggering materially riskier than a benign informational skill.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation advertises automatic config generation, process startup, workflow execution, dependency installation, image download, and broad filesystem path scanning across multiple drives and mount points without a prominent warning or explicit consent boundary. In an agent skill, these behaviors meaningfully expand execution and privacy risk because a user may issue a simple generation request without realizing the skill will inspect many filesystem locations and modify the environment.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill documentation describes capabilities that imply filesystem access, process launching, browser automation, and network communication, but the manifest does not declare any tool scope or permission boundaries. This is dangerous because consumers and execution frameworks cannot accurately constrain what the skill is allowed to do, increasing the risk of over-privileged execution and unintended local or network access.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest says the skill executes workflows via REST API, but the documentation additionally states it controls an Edge browser through the CDP protocol. This inconsistency is dangerous because browser automation via CDP materially expands capability and risk, including automated interaction with local browser state, pages, and potentially authenticated sessions, without being clearly declared in the manifest.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The primary description and operational documentation are presented in Chinese, including workflow names and usage examples, with no indication that another language is supported or that the language requirement is optional. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python file contains user-facing natural-language instructions entirely in Chinese, including the top-level docstring and later CLI usage/help text. That imposes a specific language on users without offering a language/locale choice, which matches the language-policy violation criteria.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The script iterates over all environment variables and deletes any whose name contains 'proxy', globally disabling proxy settings for all subsequent network activity in the process. That exceeds the stated purpose of running ComfyUI via local REST/CDP and can bypass enterprise monitoring, egress controls, and user-configured routing, making the skill materially more suspicious in context.

Tainted flow: 'req' from urllib.request.urlopen (line 420, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Content
try:
                    del_url = f"http://127.0.0.1:{COMFYUI_PORT}/queue/pending/{prompt_id}"
                    req = urllib.request.Request(del_url, method="DELETE")
                    urllib.request.urlopen(req, timeout=5)
                    print(f"Cleared stale queue entry: {prompt_id[:20]}")
                except:
                    pass
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
startupinfo.wShowWindow = subprocess.SW_HIDE  # 隐藏窗口
                
                try:
                    self.process = subprocess.Popen(
                        cmd,
                        cwd=self.comfyui_root,
                        startupinfo=startupinfo,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
startupinfo.wShowWindow = subprocess.SW_HIDE  # 隐藏窗口
                
                try:
                    self.process = subprocess.Popen(
                        cmd,
                        cwd=self.comfyui_root,
                        startupinfo=startupinfo,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
elif system in ("linux", "wsl", "darwin"):
                # ========== Linux/macOS 启动 ==========
                # start_new_session: 创建独立会话,关闭终端后进程继续运行
                self.process = subprocess.Popen(
                    cmd,
                    cwd=self.comfyui_root,
                    stdout=subprocess.DEVNULL,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

External Transmission

Medium
Category
Data Exfiltration
Content
}
        
        try:
            r = requests.post(f"{self.base_url}/prompt", json=data, timeout=10)
            if r.status_code == 200:
                return r.json().get("prompt_id")
            else:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The skill description suggests workflow execution via local REST API, but the file also silently installs Python packages at runtime. This expands the skill's capability beyond its declared purpose and increases host modification and supply-chain exposure without clear user awareness.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The package installation occurs automatically and without any explicit confirmation flow. This violates least surprise, can alter the user's environment, and may trigger network access or policy violations unexpectedly.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
importlib.import_module(mod_name)
        except ImportError:
            print(f"[INFO] Installing dependency: {pkg}")
            subprocess.check_call([sys.executable, "-m", "pip", "install", pkg, "-q"])


def quick_generate(prompt: str, **kwargs) -> Dict:
Confidence
98% confidence
Finding
The code automatically invokes pip at runtime to install packages without user confirmation. This executes a package manager operation in the local environment, can modify the host unexpectedly, and creates supply-chain risk if package resolution is tampered with or a malicious mirror/index is used.

Static analysis

No suspicious patterns detected.