Blog
LangflowCVE-2026-0768Sicurezza AI StackFurto di Credenziali

Langflow CVE-2026-0768: un endpoint trasforma il tuo AI stack in una shell Python

CVE-2026-0768 dà agli attaccanti Python come root sui server Langflow esposti — e stanno già rubando chiavi OpenAI e AWS. Perché l'AI stack è il bersaglio facile.

Zero Hunt Research··9 min di lettura

Nel fine settimana del 30 agosto 2026 i sensori canary di VulnCheck si sono accesi. Cinquanta tentativi di sfruttamento andati a segno nelle prime ore; entro lunedì, oltre 360. Il bersaglio non era un hypervisor, un identity provider o un'appliance di edge. Era Langflow — il costruttore low-code con cui si assemblano gli agenti LLM — e la vulnerabilità, CVE-2026-0768, consegna a un attaccante non autenticato l'esecuzione di Python arbitrario come root. La prima cosa che gli attaccanti hanno fatto è stata leggere l'ambiente in cerca di OPENAI_API* e AWS_SECRET*. L'AI stack è diventato il bersaglio facile, e chi ci entra sa esattamente quali segreti rendono il viaggio conveniente.

Cos'è davvero CVE-2026-0768

Langflow offre una funzione di validazione perché chi costruisce i flussi possa controllare che il Python di un componente personalizzato compili prima di inserirlo. Quel controllo vive su /api/v1/validate/code, e per validare il codice lo esegue. CVE-2026-0768 è la conseguenza: un parametro code che raggiunge l'interprete Python senza una sanitizzazione seria, sfruttato come code injection CWE-94. Il punteggio CVSS è 9.8, e il vettore conta più del numero — AV:N/AC:L/PR:N/UI:N significa raggiungibile in rete, complessità bassa, nessun privilegio e nessuna interazione dell'utente richiesti. Chi riesce a inviare una richiesta HTTP alla tua istanza Langflow può eseguire codice nel contesto dell'utente root.

Python peggiora le cose rispetto a un banale bug "eval della stringa". Le espressioni nei decoratori e negli argomenti di default vengono valutate nel momento in cui l'interprete analizza una funzione — prima che venga chiamata. Quindi un payload non ha bisogno che il validatore esegua la funzione inviata: inserire l'espressione malevola in un decoratore fa scattare l'esecuzione già in fase di parsing. Validare, in altre parole, è già sfruttare.

Lo stesso endpoint, per la terza volta

Se la cosa suona familiare, dovrebbe. L'endpoint /api/v1/validate/code è una calamita ricorrente per l'RCE, e CVE-2026-0768 è almeno il terzo difetto serio a passare di lì.

Vale la pena dire la genealogia con chiarezza, perché è la storia vera:

  • CVE-2025-3248 (CVSS 9.8): lo stesso endpoint faceva passare Python non fidato attraverso exec() senza autenticazione e senza sandbox. Langflow lo ha corretto in 1.3.0 imponendo un JWT o una API key sull'endpoint. È finito nel catalogo CISA KEV dopo essere stato usato dalla botnet Flodrix — e, cosa più grave, dal ransomware JadePuffer, in cui un agente LLM autonomo ha condotto l'intera kill chain: ricognizione, furto delle chiavi API cloud, movimento laterale verso i database di produzione e cifratura dei dati.
  • Correzioni successive che non erano correzioni. JFrog ha documentato che una release Langflow "patchata" successiva rimaneva sfruttabile — il percorso di validazione continuava a ritrovare la strada verso l'esecuzione di codice.
  • CVE-2026-0768 arriva ora di nuovo non autenticata (PR:N). Qualunque guardia dovesse stare davanti all'esecuzione di codice è stata aggirata un'altra volta.

"Abbiamo patchato Langflow a marzo. Siamo coperti." "Quale CVE avete patchato, e la correzione è sopravvissuta alla release successiva? Perché l'endpoint che a marzo eseguiva Python arbitrario lo esegue di nuovo — e stavolta non serve nemmeno un token."

È lo schema dietro la maggior parte dei post-mortem "eravamo patchati e ci hanno bucato lo stesso": la correzione ha chiuso una porta su una versione, e la funzione che proteggeva — eseguire codice fornito dall'utente — non è mai stata rimossa, solo recintata. E i recinti attorno a quella funzione continuano a essere scavalcati.

Perché l'AI stack è il bersaglio facile

Guarda cosa hanno cercato gli attaccanti nell'istante in cui hanno avuto una shell. Secondo VulnCheck, le richieste interrogavano queste variabili d'ambiente e questi file:

  • LANGFLOW_SUPERUSER — le credenziali admin dell'istanza Langflow stessa.
  • OPENAI_API* — le chiavi del provider di modelli. Rubate, diventano la bolletta di inferenza di qualcun altro e l'accesso di qualcun altro ai tuoi modelli fine-tuned e ai tuoi prompt.
  • AWS_ACCESS*, AWS_SECRET* — credenziali cloud, il pivot da "una scatola AI" a "tutto il tuo account".
  • /root/.cache/langflow/secret_key — il segreto applicativo che firma le sessioni di Langflow.
  • Accesso .ssh e dimensione di .bash_history — ricognizione per il movimento laterale e per capire cosa ha fatto l'operatore sull'host.

Non è una razzia a caso. È una lista della spesa scritta da qualcuno che sa che un server di orchestrazione AI è un concentratore di credenziali. Il senso di Langflow è proprio tenere le chiavi dei tuoi provider di modelli, dei tuoi database vettoriali e dei servizi cloud che i tuoi agenti richiamano. Buchi l'orchestratore ed erediti tutto in un salto. L'incidente JadePuffer del 2025 ha già dimostrato il finale — un agente che rubava chiavi cloud e passava ai database di produzione. CVE-2026-0768 è la stessa porta, riaperta, con lo stesso bottino dietro.

C'è un secondo fronte nella stessa campagna. VulnCheck riferisce che gli operatori sfruttavano contemporaneamente CVE-2026-66066 — "KindaRails2Shell", un difetto CVSS 9.5 in Active Storage di Ruby on Rails. Una discrepanza nel modo in cui Active Storage e libvips leggono un'immagine caricata permette a un attaccante di esfiltrare secret_key_base, la master key di Rails, le password dei database e i token cloud, per poi arrivare all'RCE. Da notare: la patch del vendor (Rails 8.1.3.1) blocca la lettura file via libvips, ma il gadget RCE continua a eseguire su un server patchato se si dispone di una firma valida — ed è proprio il secret_key_base esfiltrato a rendere quella firma falsificabile. Patchare e ruotare, oppure la patch è cosmetica.

Due playbook sulla stessa porta

Lo sfruttamento non è monolitico. Nell'analisi più ampia della campagna Langflow di VulnCheck, lo stesso endpoint ha alimentato due operatori molto diversi — un promemoria utile sul fatto che un singolo CVE è una porta, non una destinazione:

"Prendi le credenziali e scappa" "Accendi i miner"
Prima mossa Harvester di credenziali in Python Deploy del cryptominer
Persistenza Proxy agent, SimpleHelp RAT .sysd / .cache-sysd, .watchdog.sh, cron
C2 Beacon IRC (185.117.74[.]172:6667) Pool del miner + check-in botnet
Obiettivo Furto chiavi cloud/API, movimento laterale Monetizzare la CPU ("pearl-miner" XMR)
Segno Esfiltrazione verso 23.234.98[.]182:9999 auditd disabilitato, scansione PocSuite3 per il pivot

Stessa vulnerabilità, due economie. L'ondata attuale di CVE-2026-0768 — traffico d'origine prevalentemente dalla Russia, che rilascia un harvester di credenziali in Python, proxy agent, un SimpleHelp RAT e un miner XMR — sembra che entrambi gli operatori si siano presentati alla stessa porta aperta nello stesso momento.

Remediation

Considera qualunque istanza Langflow raggiungibile da internet come già compromessa finché non provi il contrario. Il comportamento di ricognizione-dei-segreti significa che il furto di credenziali è l'impatto di primo ordine; presumi che le chiavi siano perse e lavora a ritroso.

1. Sono interessato?

Individua le tue istanze Langflow e verifica se la superficie di validazione codice è raggiungibile:

# Individua Langflow esposto (porta di default 7860)
curl -s -o /dev/null -w "%{http_code}" http://TARGET:7860/health

# L'endpoint di validazione codice è raggiungibile senza auth?
curl -s -X POST http://TARGET:7860/api/v1/validate/code \
  -H 'Content-Type: application/json' \
  -d '{"code":"1+1"}' -o /dev/null -w "%{http_code}\n"
# Un 200/422 che elabora il body senza un 401/403 = esposto e pericoloso.

Shodan/Censys con title:"Langflow" o la porta di default ti mostrano ciò che vede un attaccante. Qualsiasi cosa risponda da un IP pubblico rientra nel perimetro.

2. Patch — e non fidarti di un solo bump di versione

Aggiorna all'ultima release di Langflow, poi verifica che la correzione tenga — lo storico delle patch dell'endpoint (CVE-2025-3248 corretto in 1.3.0, release successive ri-rotte secondo JFrog) è esattamente il motivo per cui "abbiamo aggiornato" non equivale a "siamo al sicuro". Dopo l'upgrade, rilancia la sonda non autenticata POST /api/v1/validate/code qui sopra: deve essere rifiutata senza credenziali. Per il difetto Rails co-sfruttato, aggiorna a 8.1.3.1 o successiva e ruota secret_key_base — la sola patch lascia il gadget RCE raggiungibile con una chiave di firma rubata.

3. Non puoi patchare subito? Controlli compensativi

  • Togli Langflow da internet. Non è mai stato pensato come servizio pubblico. Mettilo dietro una VPN o un reverse proxy con autenticazione; limita gli endpoint /api/v1/validate/* e di build ai soli range interni.
  • Eseguilo non-root, in container. L'esecuzione come root è ciò che trasforma la code injection in takeover completo dell'host. Un container hardenizzato, non-root, con filesystem in sola lettura riduce il raggio d'azione.
  • Togli i segreti dall'ambiente del processo. Le variabili d'ambiente sono la prima cosa letta. Sposta OPENAI_API_KEY, AWS_SECRET_ACCESS_KEY e simili in un broker di segreti con token a vita breve e con scope ristretto, così un valore rubato scade in fretta.

4. Caccia alla compromissione (mappata su MITRE ATT&CK)

  • Accesso iniziale — T1190 (Exploit Public-Facing Application): POST verso /api/v1/validate/code con body contenenti import, os., subprocess, __ (dunder) o sintassi di decoratori (@). Ogni richiesta simile da fonte esterna è un tentativo di sfruttamento.
  • Esecuzione — T1059.006 (Python): processi figli python/sh inattesi generati dal processo Langflow.
  • Accesso alle credenziali — T1552.001 / T1552.005: letture di /root/.cache/langflow/secret_key, .bash_history, .ssh/ e dump dell'ambiente di processo che riferiscono OPENAI_API, AWS_SECRET, LANGFLOW_SUPERUSER.
  • C2 / esfiltrazione — T1071 / T1571: IRC in uscita (:6667) o TCP grezzo verso porte alte come :9999; confronta con gli IOC osservati 185.117.74[.]172:6667 e 23.234.98[.]182:9999, e con eventuali installazioni di SimpleHelp RAT.
  • Persistenza / impatto — T1053.003 / T1496: nuove voci cron (es. strani /usr/bin/*.sh), file .sysd/.watchdog.sh, auditd fermato, CPU sostenuta da un miner XMR.

5. Eradicare + verificare

Patchare una macchina che ha già eseguito Python d'attacco non la ripulisce. Rimuovi gli impianti (RAT, miner, cron, .sysd/.watchdog.sh), poi ruota ogni segreto che è transitato su quell'host o nelle sue vicinanze — chiavi OpenAI e di altri provider di modelli, access key AWS, il secret_key e il superuser di Langflow, le credenziali dei database che la scatola poteva raggiungere, e il secret_key_base di Rails se KindaRails2Shell era in gioco. Ruota dopo che l'host è pulito, altrimenti consegni le nuove chiavi indietro. Conferma la pulizia reimmaginando dove possibile e osservando l'egress per le firme C2 sopra.

Dove si inserisce Zero Hunt

La verità scomoda di CVE-2026-0768 è il tempo. L'endpoint è stato ri-rotto, uno scanner ha trovato la tua istanza e 360 host sono stati colpiti prima che la maggior parte dei difensori leggesse l'advisory. Un pentest annuale — o anche trimestrale — è strutturalmente cieco a tutto questo: la tua scatola Langflow poteva non esistere all'ultimo ingaggio, e il CVE di sicuro non esisteva.

È per questo che è costruito il pentest generativo change-triggered di Zero Hunt. Un nuovo asset che compare sul perimetro — un server Langflow tirato su venerdì da un team di data science — fa scattare una campagna completa entro l'ora, senza aspettare la finestra pianificata successiva. Gli agenti Recon ed Exploit dello swarm a 10 agenti scrivono una catena di exploit specifica per il target contro l'esatta superficie /api/v1/validate/code, usando un LLM locale invece di un PoC pubblico, così che il finding rifletta la tua installazione e non un template generico. Ogni skill candidata è backtestata nell'AI Gym contro un corpus di esercizi CVE black-box prima di girare su un asset live, e ogni finding è firmato ECDSA al momento della scrittura — così quando l'auditor chiede perché un orchestratore AI esposto su internet con privilegi di root non sia mai stato segnalato, hai una risposta datata e verificabile invece di un'alzata di spalle. Chiude esattamente la falla che l'agente JadePuffer ha attraversato nel 2025: un attaccante autonomo che valida l'esposizione più in fretta di quanto possa fare un calendario umano.

E poiché qui la prima mossa è il furto di credenziali seguito dall'egress — un harvester Python che chiama casa, un SimpleHelp RAT che fa beacon, un miner XMR che entra in un pool — l'AI Traffic Analysis di Zero Hunt sorveglia il filo per la seconda metà della storia. Il suo modello deep-learning, con quattro teste di inferenza a velocità multi-gigabit sulla GPU dell'appliance, segnala la sessione anomala in uscita verso un ASN mai visto e il check-in regolare del miner mentre l'esfiltrazione sta avvenendo, non nel digest SIEM del mattino dopo — che, su una scatola il cui unico compito era custodire le tue chiavi dei modelli e del cloud, è la differenza tra ruotare una chiave e spiegare una violazione.