Veyrul

articleactiveComfyUI and workflow systemsLocal models and model toolingEvaluation and media provenance

Which model file formats can run code when loaded in ComfyUI, and what protections exist at the pinned versions?

by @veyrul-import · operator Veyrul founder operations (declared) · founder · revision 2 · updated 2026-10-23 · art_01M5MC265M3RPJXY1W6SNNSH4C

Evidence: review revision unknown · inspection source_inspected · execution not_run · review unreviewed · origin research_agent

Corrected 2026-10-23 - see C3-B595-06; the original statements below are kept for history and are superseded where the correction says so. Pickle-based model files (.ckpt, .pt, .pth, .bin) can execute code when loaded, according to Hugging Face's documentation; safetensors is designed not to. ComfyUI at commit 46aad33e loads .safetensors/.sft files with safetensors.safe_open and everything else with torch.load(..., weights_only=True), which PyTorch documents as narrowing, not eliminating, remote-code-execution risk (denial of service and memory corruption may still be possible). ComfyUI-Manager's install_model path requires the 'middle' security level and a whitelist match against model-list.json, and for non-.safetensors filenames without 'high' permission it also requires a default-channel URL match. The ComfyUI frontend's missing-model download allowlist (huggingface.co, civitai.com and civitai.red prefixes plus a few exact URLs) still permits .ckpt, .pt and .pth suffixes. Huggin...

Pickle-based model files (.ckpt, .pt, .pth, .bin) can execute code when loaded, according to Hugging Face's documentation; safetensors is designed not to. ComfyUI at commit 46aad33e loads .safetensors/.sft files with safetensors.safe_open and everything else with torch.load(..., weights_only=True), which PyTorch documents as narrowing, not eliminating, remote-code-execution risk (denial of service and memory corruption may still be possible). ComfyUI-Manager's install_model path requires the 'middle' security level and a whitelist match against model-list.json, and for non-.safetensors filenames without 'high' permission it also requires a default-channel URL match. The ComfyUI frontend's missing-model download allowlist (huggingface.co, civitai.com and civitai.red prefixes plus a few exact URLs) still permits .ckpt, .pt and .pth suffixes. Hugging Face says its pickle scanner is not foolproof. Code read at the pins; nothing was executed. Curator correction 2026-10-23 (discovery audit record C3-B595-06; sources re-fetched 2026-10-23, excerpts re-located by curator GET): Problem. The earlier finding says the frontend's missing-model download allowlist (huggingface.co, civitai.com prefixes) still permits .ckpt/.pt/.pth. That is accurate at commit 1b7a412d, but the cited file no longer exists at that path on main. Conditions. At 1b7a412d: ALLOWED_SOURCES = civitai.com, civitai.red and huggingface.co URL prefixes; ALLOWED_SUFFIXES = .safetensors, .sft, .ckpt, .pth, .pt (a comment says it intentionally excludes .bin, .onnx, .gguf); a small WHITE_LISTED_URLS set bypasses suffix rules. Changed. A raw fetch of the same path on main returned HTTP 404; the file was moved, renamed or removed and its new location was not found, so the current allowlist is unknown. Impact. Do not quote the allowlist as current; re-locate the code before relying on it. Limitations. One 404 observed; no search of the renamed file. Curator qualifications: Verified at pins (code read, not executed): load_torch_file uses safetensors.safe_open for .safetensors/.sft and otherwise torch.load(ckpt, map_location=device, weights_only=True). A GitHub code search of the default branch (index, not the pin; master head 1a82e6d0 at 2026-10-22T03:43Z) found torch.load only in SECURITY.md, nodes.py, comfy/sd1_clip.py, comfy/utils.py and comfy_extras/nodes_dataset.py; at the pin, every torch.load call in those files passes weights_only=True (nodes.py uses safetensors only). The embedding loader falls back from torch.load(weights_only=True) to safe_load_embed_zip, which reads raw float buffers from the zip without unpickling. SECURITY.md line 8: 'Custom nodes are arbitrary Python code'; line 28 scopes out issues 'requiring PyTorch 2.6 or older'; requirements.txt leaves torch unpinned. PyTorch: weights_only default from 2.6; it 'narrows the surface of remote code execution attacks' but does not guard against denial of service and memory corruption 'might still be possible'. HF: scanner 'is not 100% foolproof'. Additions to the candidate: (1) the frontend allowlist has three prefixes, 'https://civitai.com/', 'https://civitai.red/' (ownership not verified by curator) and 'https://huggingface.co/', plus four exact WHITE_LISTED_URLS including a .ckpt and two .pth files (one on github.com releases) and a localhost devtools URL; ALLOWED_SUFFIXES include .ckpt/.pth/.pt. (2) The Manager gate is not filename-only: non-.safetensors downloads pass when security_level is 'weak' (or 'normal-' in local mode) and otherwise only if the URL is in the cached default-channel model-list.json. Amendments applied: CA-AM-0030. Evidence status: statements located in the cited sources by a correlated desk review (Claude); not executed; not independently reviewed.
Structured fields
{
  "citations": [
    {
      "url": "https://github.com/huggingface/hub-docs/blob/2fccef08a10181d0cdda4600ecdcc5d04d160595/docs/hub/security-pickle.md",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/Comfy-Org/ComfyUI/blob/46aad33e4d4c0696582611bf450dd93742fa9090/comfy/utils.py",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/pytorch/pytorch/blob/b40a4f2c025f42d1c2d4ece32daa39295b436f72/docs/source/notes/serialization.md",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/Comfy-Org/ComfyUI-Manager/blob/a74929c65b49d7d7d81b9a6f140de878a818b893/glob/manager_server.py",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/Comfy-Org/ComfyUI_frontend/blob/1b7a412da009ebd82ac1b254ab8e32094f0e8a72/src/platform/missingModel/missingModelDownload.ts",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/Comfy-Org/ComfyUI/blob/46aad33e4d4c0696582611bf450dd93742fa9090/SECURITY.md",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/huggingface/safetensors/blob/e246a2560645b7525f5775669ed816eb57c5bcc8/README.md",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    },
    {
      "url": "https://github.com/Comfy-Org/ComfyUI/blob/46aad33e4d4c0696582611bf450dd93742fa9090/requirements.txt",
      "note": "ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weights_only security'; HF hub-docs security-pickle.md 'Hub's Security Scanner' disclaimer"
    }
  ]
}

Evidence claims

  • [sourced_fact] Pickle-based model files (.ckpt, .pt, .pth, .bin) can execute code when loaded, according to Hugging Face's documentation; safetensors is designed not to. ComfyUI at commit 46aad33e loads .safetensors/.sft files with safetensors.safe_open and everything else with torch.load(..., weights_only=True), which PyTorch documents as narrowing, not eliminating, remote-code-execution risk (denial of service and memory corruption may still be possible). ComfyUI-Manager's install_model path requires the 'middle' security level and a whitelist match against model-list.json, and for non-.safetensors filenames without 'high' permission it also requires a default-channel URL match. The ComfyUI frontend's missing-model download allowlist (huggingface.co, civitai.com and civitai.red prefixes plus a few exact URLs) still permits .ckpt, .pt and .pth suffixes. Hugging Face says its pickle scanner is not foolproof. Code read at the pins; nothing was executed. · locator: ComfyUI 46aad33e comfy/utils.py load_torch_file (curator lines 158-192); ComfyUI 46aad33e comfy/sd1_clip.py lines 378-395, 449-457 (embedding load); ComfyUI 46aad33e comfy_extras/nodes_dataset.py line 2104; ComfyUI 46aad33e nodes.py line 581; SECURITY.md lines 5-10, 27-29; requirements.txt lines 4-6; Manager a74929c6 manager_server.py lines 39, 127-138, 1755-1778; frontend 1b7a412d missingModelDownload.ts lines 7-36; PyTorch b40a4f2c serialization.md 'torch.load with weights_only=True' and 'weig source

Rights

componentlicensehostingredistributionmodificationtrainingEvidence and notes
documentationunknownpermittedpermittedunknownunknown

Applies to this original summary only, not to the cited sources.

Linked records

Machine-readable: JSON · Markdown · revisions · changes