CodeVetter · Repo Unpack · Risk map
Comfy-Org/ComfyUI
Biggest risks: there is no authentication on the HTTP API, custom nodes are arbitrary code executed at startup, and model file formats include pickle-capable extensions. The codebase has accumulated scattered path-traversal and XSS mitigations that must be replicated at every new file endpoint. The execution engine is a single shared mutable state machine (server.client_id, last_node_id, module-level registries) so concurrent or reentrant use is fragile. Memory management and the aimdo/DynamicVRAM integration contain version-dependent protocol fallbacks that are easy to break.
- No authentication exists on any route: default bind is 127.0.0.1, but --listen with no value exposes 0.0.0.0,:: — an unauthenticated API that can queue prompts, read/write userdata files, upload images, and hit /internal/logs.
- Custom nodes are arbitrary Python: execute_prestartup_script exec_modules every custom_nodes/*/prestartup_script.py before the server starts, and load_custom_node exec_modules each module — remote-code-execution by design; mitigations are only --disable-all-custom-nodes/--whitelist-custom-nodes and optional comfyui_manager policy.
- supported_pt_extensions includes .ckpt/.pt/.bin/.pkl — formats that can embed pickle payloads; loading relies on comfy.utils.load_torch_file's safe handling, so changes there are security-critical. (inferred)
- Path traversal defenses are reimplemented per endpoint: /view checks '..' and leading '/', subfolder joins use os.path.commonpath containment, and folder_paths.is_within_directory/get_annotated_filepath add realpath-based containment — any new file-serving endpoint must repeat this correctly.
- Stored-XSS mitigation is centralized in folder_paths.DANGEROUS_CONTENT_TYPES/is_dangerous_content_type with a Sec-Fetch-Dest:image carve-out for SVG; endpoints serving user content must route dangerous types to octet-stream or they reintroduce XSS.
- origin_only_middleware is an admitted partial fix for DNS-rebinding/cross-site POSTs to a loopback server ('the proper fix would be to add a cookie'): it 403s Sec-Fetch-Site:cross-site and Host/Origin hostname mismatches only when Host resolves to loopback.
- Shared mutable globals: server.client_id and last_node_id are single-slot fields on PromptServer set from extra_data of whichever prompt is running, and NODE_CLASS_MAPPINGS is a module-level dict mutated by every extension — one concurrently executing prompt or a misbehaving custom node can corrupt routing/display state. (inferred)
- comfy_aimdo protocol drift is handled by chained TypeError fallbacks (0.4.9/0.4.10 signatures) in main.py; silent wrong-version behavior is a real hazard since the fallbacks catch TypeError broadly.
- The queue item is a positional tuple where index 5 is `sensitive` extra data; _remove_sensitive_from_queue and the remove_sensitive lambda both rely on tuple position, so reordering the tuple silently leaks auth tokens into queue/history responses.
- hook_breaker_ac10a0.py is a manual save/restore shim that protects comfy.model_management.cast_to from being hooked by custom nodes — evidence that custom-node monkeypatching has caused production incidents and protection is opt-in per function.
- DB init kills the process on lock contention only when --enable-assets is set; otherwise it logs and continues with a degraded assets layer — divergence between code paths makes failures mode-dependent.
- Alembic migration 0007_record_content_split is explicitly destructive: upgrading through it discards the prior asset catalog (tags, metadata, previews, renames) keeping only a .bkp file.
- API nodes make outbound calls to dozens of paid third-party services using the user's comfy-org token; --disable-api-nodes exists as the kill switch and also adds a strict CSP header, implying these nodes are treated as the network-risk boundary.