Blog
Kestra RCECVE-2026-49869Authentication BypassAI Traffic Analysis

Kestra CVE-2026-49869: un path che finisce in /configs è root senza password

Kestra CVE-2026-49869 è una RCE non autenticata CVSS 10.0: un controllo per suffisso nel filtro di autenticazione trasforma ogni path che finisce in /configs in root. In KEV, sfruttata per cryptomining. Fix + hunting.

Zero Hunt Research··9 min di lettura

Il 2 settembre 2026 CISA ha aggiunto CVE-2026-49869 al catalogo Known Exploited Vulnerabilities. È una falla CVSS 10.0 in Kestra, la piattaforma open-source di orchestrazione dati, ed è il tipo di bug che sembra un esercizio da code review: il filtro di autenticazione decide se una richiesta ha bisogno di credenziali chiedendosi se il path finisce con /configs. Non se è /configs. Quella singola parola — endsWith invece di un confronto esatto — è l'intera vulnerabilità, e consegna a un attaccante non autenticato l'esecuzione di codice remoto come root dentro il container del worker. La patch è uscita da settimane; lo sfruttamento che l'ha portata in KEV era già in corso a fine giugno.

Cos'è davvero CVE-2026-49869

Kestra esegue le tue pipeline. Schedula workflow, esegue task e — per design — esegue codice arbitrario, perché è quello che fa un motore di orchestrazione. Proteggere l'API che crea e lancia quei workflow è quindi l'intero modello di sicurezza. CVE-2026-49869 rompe quel modello proprio alla porta d'ingresso.

L'AuthenticationFilter di Kestra OSS esenta un endpoint pubblico dalla Basic Auth, così la UI può leggere la configurazione prima del login. Lo fa con:

request.getPath().endsWith("/configs")

Il match per suffisso non è un match sul path. Qualsiasi rotta il cui path finisce nella stringa configs passa il filtro senza credenziali — incluse le rotte che creano ed eseguono i flow. L'attaccante costruisce una richiesta il cui path termina in /configs, il filtro la fa passare come "config pubblica", e la richiesta raggiunge un endpoint che costruisce volentieri un workflow ed esegue un task shell. Lo stack CWE sul record è preciso sulla stratificazione: CWE-287 autenticazione impropria che alimenta CWE-78 OS command injection, con CWE-184 (lista incompleta di input non ammessi) a indicare la causa radice — una denylist per suffisso dove serviva una allowlist per path esatto.

E non era l'unico errore di matching in quel filtro. Le stesse release corrette chiudono anche CVE-2026-53576, dove il filtro dell'API REST @Filter("/api/v1/**") gestisce male i path delle richieste e produce lo stesso risultato: creazione di flow non autenticata e RCE. Due bug distinti di matching su suffisso/prefisso nello stesso layer di autenticazione, corretti insieme. Quando un codebase ha un bug di confronto sui path, di solito ne ha due.

Dal bypass all'RCE non autenticata come root

La catena è corta, ed è per questo che il vettore CVSS (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H) è al massimo. Nessun privilegio, nessuna interazione utente, raggiungibile in rete e — il bit di scope change S:C — l'impatto esce dal componente vulnerabile verso il container in cui gira.

Attaccante: POST di una definizione di flow su un path che finisce in /configs, con un task io.kestra.plugin.scripts.shell che esegue curl … | sh. Kestra: Nessuna credenziale? Il path finisce in /configs, è la rotta di config pubblica. Consentito. Creo il flow. Eseguo il task come root. Attaccante: ora ho una reverse shell dentro il tuo runner di pipeline.

Poiché il worker esegue i task come root dentro il proprio container, la prima istruzione dell'attaccante gira già al massimo privilegio locale. Non serve un secondo exploit per l'escalation locale — il motore di orchestrazione è la primitiva di esecuzione codice, ed è stato progettato per esserlo. La vulnerabilità ha solo tolto il login.

La kill chain osservata in the wild

È la parte che conta più del bug in sé. L'attività che ha portato CVE-2026-49869 in KEV non era una proof-of-concept: era un'intrusione reale, osservata da fine giugno 2026, e la sua forma è il motivo per cui la detection lato rete conta. Ricostruita dal reporting pubblico (The Hacker News, che ha coperto il lotto di sette CVE in KEV), le fasi erano:

Fase Azione ATT&CK
Accesso iniziale Richiesta non autenticata a un path che finisce in /configs → creazione flow T1190 Exploit Public-Facing Application
Esecuzione Task shell esegue curl | sh nel worker T1059.004 Unix Shell
Ingresso Payload scaricato dall'infrastruttura dell'attaccante T1105 Ingress Tool Transfer
Discovery Enumerazione dell'ambiente container Docker T1613 Container & Resource Discovery
Raccolta/staging Output codificato e scritto nel key-value store di Kestra, non su disco T1074 Data Staged
Impatto Deploy di un miner di criptovaluta T1496 Resource Hijacking

Due dettagli rendono questo un caso da manuale per l'analisi del traffico più che per l'analisi dei log. Primo, l'operatore ha salvato l'output raccolto dentro l'interfaccia key-value di Kestra invece di scrivere file — riducendo di proposito gli artefatti su disco, dove guarda la maggior parte della detection. Secondo, la consegna iniziale era curl-pipe-shell: niente atterra come file prima di essere eseguito. Se la tua strategia di detection è "osserva il filesystem e i log applicativi", questa catena è costruita per restare silenziosa proprio su quelle superfici. Ciò che non può nascondere è la rete:

  • Il curl | sh contatta l'infrastruttura dell'attaccante — una connessione in uscita da un host che normalmente si limita a ricevere job di orchestrazione.
  • La reverse shell mantiene una sessione in uscita verso un IP che l'appliance non ha mai visto.
  • Il cryptominer apre connessioni sostenute verso una mining pool — il pattern di traffico più riconoscibile dell'intera kill chain.

Ognuno di questi è un'anomalia comportamentale sul filo, indipendente dal fatto che i log dell'host siano mai stati scritti o poi cancellati.

Perché un motore di orchestrazione è la cosa peggiore da perdere

Il blast radius è il motivo per cui questo merita trattamento d'emergenza anche se pensi di avere esposto "solo uno scheduler". Una piattaforma di orchestrazione è, per costruzione, un caveau di credenziali e una rampa di lancio per il movimento laterale:

  • Custodisce i segreti di tutto ciò che orchestra — password di database, chiavi API cloud, service token — quindi un attaccante al suo interno eredita le credenziali dell'ambiente senza toccare direttamente un secrets manager.
  • È progettata per raggiungere il resto della rete per eseguire i task, quindi egress e connettività interna sono già predisposti per lei.
  • Esegue codice arbitrario come funzione normale, quindi il codice malevolo non appare categoricamente diverso dall'esecuzione legittima di un workflow.

La storia recente di Kestra sottolinea che è un problema di classe, non un caso isolato: la stessa piattaforma ha già portato CVE-2026-34612 (SQL injection verso RCE prima della 1.3.7) e ulteriori problemi di autenticazione risolti fino alla 1.3.24. Se la esegui esposta, tratta la superficie API come un rischio permanente, non come una questione chiusa.

Remediation

Un runbook completo per CVE-2026-49869 (e per la sua gemella CVE-2026-53576, che correggi nello stesso passo).

1. Sono interessato?

Verifica la versione in esecuzione. I range affetti sono < 1.0.45 e ≥ 1.1.0, < 1.3.21.

# Banner di versione dall'API (adatta host/porta)
curl -s http://KESTRA_HOST:8080/api/v1/version || \
  docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.version" }}' <kestra_container>

# L'API è raggiungibile da fuori il tuo perimetro di fiducia? (non dovrebbe)
curl -s -o /dev/null -w '%{http_code}\n' http://KESTRA_HOST:8080/api/v1/configs

Ogni istanza Kestra la cui API è raggiungibile da una rete non fidata e con versione inferiore a quella corretta è sfruttabile senza credenziali. Assumi che esposta = compromessa finché non hai fatto hunting (passo 4).

2. Patch — versioni corrette esatte

Aggiorna a 1.0.45 (linea 1.0.x) o 1.3.21 (linea 1.3.x) o successive, come da security advisory Kestra e dal record CVE. Queste release sostituiscono il matching per suffisso/prefisso nel filtro di autenticazione con controlli su path esatto e chiudono sia CVE-2026-49869 sia CVE-2026-53576. Questo è l'unico fix reale — tutto ciò che segue compra tempo, non sicurezza.

3. Non puoi applicare la patch subito? Controlli compensativi

  • Non esporre l'API di Kestra a internet. Mettila dietro un reverse proxy o una VPN e limitala a sorgenti admin note. Questo da solo elimina il prerequisito "non autenticato da remoto".
  • Aggiungi una allowlist per path esatto sul proxy. Poiché il bug è il match per suffisso, blocca qualsiasi richiesta il cui path contiene /configs ma non è esattamente la rotta di config prevista, e nega path traversal / trucchi con segmenti finali. Normalizza i path sul proxy prima che raggiungano Kestra.
  • Blinda l'egress dal worker. Un runner di pipeline raramente ha bisogno di iniziare connessioni in uscita arbitrarie. Un default-deny in uscita neutralizza il curl | sh, la reverse shell e il check-in verso la mining pool in un colpo solo.
  • Non montare mai il socket Docker nel container di Kestra a meno che un task lo richieda davvero — trasforma l'RCE sul worker in takeover dell'host.

4. Hunting della compromissione

Assumi che la finestra si sia aperta a giugno. Guarda sulla rete e nel container, non solo nei log (l'operatore ha minimizzato di proposito gli artefatti su disco):

  • Anomalie in uscita (lato rete): egress inatteso dall'host Kestra, in particolare curl/wget verso IP sconosciuti, sessioni TCP in uscita mantenute a lungo (reverse shell) e connessioni verso endpoint Stratum/mining pool — mappa su T1496 (Sigma: Network Communication With Crypto Mining Pool) e T1059.004 (Sigma: Suspicious Reverse Shell Command Line).
  • Lato processo/host: processi miner (CPU alta e sostenuta), processi shell figli del worker Kestra, curl … | sh nella cronologia dei processi.
  • Lato applicativo: flow che non hai creato tu, specie flow recenti che contengono task shell/script; scritture anomale nel key-value store usato come canale di staging (T1074).
  • Lato accesso: qualsiasi richiesta andata a buon fine verso un path che finisce in /configs che non fosse l'endpoint di config legittimo.

5. Eradicazione e verifica

  1. Isola l'host, termina il miner e i processi di reverse shell, rimuovi i flow e le voci KV creati dall'attaccante.
  2. Ruota ogni segreto che Kestra poteva raggiungere — credenziali di database, chiavi cloud, service token. Root nel worker significa che sono tutti bruciati.
  3. Ricostruisci il container da un'immagine pulita invece di ripulire in place.
  4. Applica la patch a 1.0.45 / 1.3.21, poi ri-verifica: conferma che la richiesta con suffisso /configs ora risponda 401/403 e che l'egress default-deny sia applicato. Verifica dopo la patch, non prima.

Dove si inserisce Zero Hunt

Il tratto distintivo di questa intrusione è che è stata ingegnerizzata per restare silenziosa su disco e nei log — curl | sh senza file scritti, staging dentro il key-value store dell'applicazione stessa, root in un container i cui log l'attaccante poteva cancellare. È esattamente il fallimento per cui è costruita l'AI Traffic Analysis di Zero Hunt. L'appliance esegue un modello di deep learning proprietario con quattro teste di inferenza parallele (traffico sospetto, classificazione malware, identificazione tipo di attacco, fingerprinting applicativo) sul traffico live a 2,7+ Gbit/s, sulla GPU dell'appliance, senza callback verso il cloud. Non ha bisogno che i log dell'host siano integri, perché legge l'unica superficie che all'attaccante resta da usare: il filo. Il curl in uscita verso infrastruttura mai vista, la sessione di reverse shell e il check-in verso la mining pool sono tutte anomalie comportamentali che il modello segnala mentre il miner si sta ancora avviando — non nel digest SIEM di domani.

Il lato generativo chiude il cerchio prima che un attaccante trovi la porta. Lo swarm di 10 agenti di Zero Hunt tratta un'API di orchestrazione appena esposta come un evento change-triggered: un nuovo asset sul perimetro avvia una campagna completa entro un'ora, e l'agente Exploit scrive un tentativo per-target contro il tuo deployment reale — inclusa proprio quella classe di bypass di autenticazione per suffisso che CVE-2026-49869 rappresenta — validato nell'AI Gym contro il corpus Vulhub-Bench prima di girare in produzione, con ogni finding firmato in ECDSA per la catena di custodia. Il punto non è dirti che Kestra aveva una CVE: l'ha già fatto la cronaca. Il punto è dimostrare, in continuo, se la tua istanza è raggiungibile e sfruttabile — e vederlo sulla rete nell'istante in cui qualcun altro lo dimostra al posto tuo.

CVE-2026-49869 è un bug di una parola con un blast radius che copre l'intero ambiente. Applica oggi la patch a 1.0.45 o 1.3.21, togli l'API da internet e assumi che qualsiasi cosa raggiungibile da giugno abbia eseguito i workflow di qualcun altro.