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
CVE-2026-34207 — Il filtro SSRF controllava il testo dell'hostname, ma la destinazione effettiva veniva decisa successivamente dal DNS. Questo gap permetteva agli URL Webhook controllati dall'attaccante di raggiungere destinazioni di loopback, metadata e rete privata. | Kitploit
Strumenti/GitHubGitHub/0xmrma/cve-2026-34207
Analisi delle VulnerabilitàExploitSicurezza WebPenetration TestingPaper e RicercaApprendimento e Formazione
GitHub0xmrma/cve-2026-34207

CVE-2026-34207

Il filtro SSRF controllava il testo dell'hostname, ma la destinazione effettiva veniva decisa successivamente dal DNS. Questo gap permetteva agli URL Webhook controllati dall'attaccante di raggiungere destinazioni di loopback, metadata e rete privata.

Vedi Repository
1 mese 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-34207

Il filtro SSRF controllava il testo del nome host, ma la destinazione effettiva veniva decisa successivamente dal DNS. Questa lacuna permetteva agli URL Webhook controllati dall'attaccante di raggiungere destinazioni loopback, metadata e rete privata.

Introduzione

Ho trovato questo problema mentre esaminavo Typebot, un costruttore di chatbot open-source, con una semplice domanda di sicurezza in mente:

Cosa succede se la protezione SSRF convalida il testo del nome host, ma la destinazione reale viene decisa successivamente dal DNS?

In questo caso, quella domanda ha portato a un bug reale.

La protezione SSRF di Typebot per i blocchi Webhook / Richiesta HTTP convalidava solo:

  • la stringa URL,
  • i nomi host letterali bloccati,
  • e i formati IP letterali

Non risolveva i nomi host prima di autorizzare la richiesta.

Ciò significava che un nome host come ssrf-repro.example poteva sembrare innocuo durante la convalida, per poi risolversi in:

  • 127.0.0.1
  • 169.254.169.254
  • o spazio di rete RFC1918/privato

ed essere comunque recuperato dal client HTTP backend.

Questo problema è diventato CVE-2026-34207.

Typebot: Typebot su GitHub
CVE: CVE-2026-34207
Corretto in: 3.16.0

Questo ha interessato Typebot, una piattaforma chatbot open-source ampiamente utilizzata. Sul suo sito ufficiale, Typebot si presenta come affidabile per oltre 650 aziende in tutto il mondo. Il sito pubblicizza anche oltre 2 milioni di chat mensili e oltre 1,5 milioni di bot pubblicati.

photo0

Catena d'attacco

URL Webhook controllato dall'attaccante -> il nome host supera la convalida SSRF solo letterale -> nessuna risoluzione DNS prima della decisione di autorizzazione -> il client HTTP backend risolve il nome host in una destinazione interna -> la richiesta lato server raggiunge loopback / metadata / rete privata -> i dati della risposta diventano disponibili tramite i log di esecuzione


Cosa fa Typebot

Typebot è un costruttore di chatbot.

Permette agli utenti di creare flussi che possono:

  • fare domande
  • raccogliere input strutturati
  • chiamare servizi esterni
  • concatenare logiche di business
  • e attivare richieste HTTP in uscita tramite blocchi Webhook / Richiesta HTTP

Ciò significa che l'esecuzione di richieste in uscita è un vero e proprio confine di sicurezza.

La domanda importante qui non era se Typebot supportasse i blocchi Webhook.

La vera domanda era:

La protezione SSRF convalida la destinazione effettiva a cui il server si collegherà, o solo il testo del nome host che appare nell'URL?

In questo caso, convalidava solo prima la forma testuale.

Questo è stato l'errore.


Perché questa superficie valeva la pena di essere esaminata

Le difese SSRF falliscono in modi molto prevedibili.

La maggior parte delle volte, gli errori interessanti non sono:

  • "ti sei dimenticato di bloccare 169.254.169.254"
  • o "ti sei dimenticato di bloccare localhost"

Gli errori più forti sono errori di confine:

  • la convalida avviene prima della canonicalizzazione
  • la convalida avviene prima dei reindirizzamenti
  • la convalida avviene prima della risoluzione DNS
  • la convalida avviene su una rappresentazione, ma lo stack di rete ne usa un'altra

Qui era il posto giusto dove guardare.

Typebot aveva già una logica di hardening SSRF per IP metadata letterali, loopback, intervalli privati e trucchi IP codificati.

Questo rendeva ovvia la domanda successiva:

Cosa succede se il nome host non è letteralmente pericoloso, ma si risolve in una destinazione pericolosa successivamente?

Questo è esattamente ciò che è successo.


Causa principale

Il problema principale era la convalida della destinazione basata sul testo del nome host invece che sull'indirizzo IP risolto.

Nell'implementazione vulnerabile, validateHttpReqUrl():

  • analizzava l'URL
  • permetteva solo http: e https:
  • bloccava un breve elenco di nomi host letterali come metadata.google.internal, metadata.goog, metadata e localhost
  • rilevava trucchi IP decimali / esadecimali / ottali letterali
  • analizzava indirizzi IPv4 / IPv6 letterali
  • convalidava l'indirizzo solo se il nome host stesso era già un IP letterale

Questa è la parte importante.

Se il nome host era un valore normale come:

ssrf-repro.example

allora parseIPAddress(hostname) restituiva null, e il validatore si fermava lì.

Non avveniva alcuna risoluzione DNS prima dell'approvazione.

Quindi la logica vulnerabile si riduceva effettivamente a:

root@kitploit:~
const ip = parseIPAddress(hostname);
if (ip) {
  validateIPAddress(ip);
}

Ciò significa che:

  • gli IP pericolosi letterali erano bloccati
  • gli IP pericolosi codificati erano bloccati
  • ma i nomi host che si risolvevano in IP pericolosi non lo erano

La seconda metà del bug era nel percorso di esecuzione.

In executeHttpRequest(), Typebot eseguiva prima la convalida e poi successivamente effettuava la richiesta effettiva con ky(request.url, ...).

Quindi la sequenza era:

  • convalidare la stringa URL
  • accettare il nome host
  • successivamente risolvere il nome host durante la richiesta in uscita reale
  • connettersi alla destinazione interna risolta

Questa è l'intera vulnerabilità.


Perché questo è un problema di sicurezza, non solo un filtraggio incompleto

La distinzione importante è dove è stata presa la decisione di fiducia.

Molti bug sembrano piccoli se li descrivi male.

Se descrivi questo come:

"il filtro del nome host era incompleto"

sembra un problema di qualità.

Questo non è il vero problema.

Il vero problema era:

  • il server prendeva una decisione di sicurezza prima di conoscere la destinazione reale
  • lo stack di rete si connetteva successivamente da qualche altra parte
  • e l'applicazione trattava quella richiesta come valida

Questa non è una debolezza di filtraggio estetica.

È un fallimento del confine di fiducia.

E poiché l'esecutore HTTP registrava i dati di risposta nei log di esecuzione, il problema non era nemmeno cieco nei casi più forti.

Quindi non era solo:

  • "si è verificato traffico interno inaspettato"

Era:

  • si è verificato traffico interno
  • e l'attaccante poteva spesso recuperare prove e contenuto della risposta attraverso il normale comportamento dell'applicazione

Questa è una vera vulnerabilità SSRF.


Prova di concetto

Ho usato due livelli di prova perché dimostravano due cose diverse.

PoC 1: demo locale autonoma del resolver

La prima PoC isolava pulitamente la causa principale.

Ho usato un piccolo harness locale che:

  • avviava un server HTTP loopback su 127.0.0.1
  • convalidava un URL come http://ssrf-repro.example:18080/...
  • usava un resolver controllato in modo che ssrf-repro.example si risolvesse in 127.0.0.1
  • poi eseguiva la richiesta

Questo dimostrava l'esatto difetto:

  • la convalida passava perché il nome host non era un valore letterale bloccato
  • la richiesta successiva raggiungeva comunque il loopback

L'output catturato mostrava:

  • risultato del validatore: passato
  • risultato dell'esecuzione della richiesta: loopback raggiunto
  • corpo della risposta restituito dal servizio loopback

Questo dimostrava direttamente la lacuna di convalida.


PoC 2: percorso di esecuzione reale di Typebot

La seconda PoC mostrava il bug attraverso il percorso di funzionalità effettivo che conta.

La riproduzione più semplice era:

  1. Mappare un nome host benigno sul loopback della macchina dove Typebot backend risolve il DNS
  2. Avviare un servizio HTTP locale
  3. Creare un blocco Webhook che punta a quel nome host benigno
  4. Attivare il blocco attraverso un normale percorso di anteprima autenticata o di esecuzione live

Un blocco rappresentativo appariva così:

root@kitploit:~
{
  "id": "blk-webhook",
  "type": "Webhook",
  "options": {
    "webhook": {
      "method": "GET",
      "url": "http://ssrf-repro.example:8000/"
    }
  }
}

Con una voce nel file hosts come:

root@kitploit:~
127.0.0.1 ssrf-repro.example

il validatore accettava comunque l'URL perché:

  • ssrf-repro.example non era in blockedHostnames
  • non era localhost
  • parseIPAddress("ssrf-repro.example") restituiva null
  • non avveniva alcuna convalida dell'IP di destinazione

Poi il client HTTP backend risolveva il nome host in 127.0.0.1 e si collegava comunque.

Questo stabiliva l'intera affermazione:

  • la logica di convalida vulnerabile era raggiungibile nell'uso reale delle funzionalità
  • la richiesta colpiva una classe di destinazione bloccata
  • e l'applicazione la trattava comunque come una richiesta HTTP in uscita riuscita

Perché le due PoC sono state scelte in questo modo

La prima PoC dimostra la causa principale.

La seconda PoC dimostra l'impatto sul prodotto.

Questa divisione è importante.

Se mostri solo:

"questo filtro accetta un nome host"

non hai mostrato abbastanza.

Se mostri solo:

"si è verificata una richiesta interna"

non hai isolato il perché.

Il report più forte è:

  • la convalida basata sul nome host ha accettato un valore che non avrebbe dovuto essere considerato affidabile
  • la risoluzione DNS ha successivamente cambiato il significato reale di sicurezza di quel valore
  • il backend si è collegato a una destinazione bloccata
  • e il percorso di funzionalità è comunque stato completato

Questa è la storia completa.


Gravità e classificazione

Questo problema è stato ragionevolmente classificato come Alto.

La classificazione dell'avviso era:

  • CWE-918: Server-Side Request Forgery (SSRF)
  • CWE-20: Improper Input Validation
  • CVSS:
root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L

Ha senso.

Non era di per sé un SSRF non autenticato su scala internet.

I privilegi richiesti erano Bassi perché il bug standalone richiedeva un attore che potesse configurare o attivare un blocco Webhook / Richiesta HTTP.

Ma all'interno di quel confine, l'impatto era serio:

  • accesso al loopback
  • accesso alla rete privata
  • accesso ai metadata
  • e esfiltrazione delle risposte tramite log

Questo è un forte problema SSRF da solo.

E diventa ancora più pericoloso se combinato con altri bug che ampliano la raggiungibilità.


Perché valeva comunque la pena segnalarlo

Alcune persone vedono un SSRF autenticato e lo sottovalutano immediatamente.

Questo è un errore.

La vera domanda non è:

"L'attaccante era loggato?"

La vera domanda è:

"Poteva quell'attaccante far connettere il server a un luogo che il modello di sicurezza avrebbe dovuto proibire?"

Qui, la risposta era sì.

Il validatore affermava di proteggere:

  • servizi metadata
  • loopback
  • intervalli privati RFC1918
  • intervalli locali IPv6

Ma una lacuna nella risoluzione del nome host permetteva a quelle stesse destinazioni di rientrare attraverso una rappresentazione diversa.

Questo è esattamente il tipo di bug che merita un CVE.


Analisi della correzione

La correzione era solida perché correggeva il confine reale, non solo un sintomo.

Nell'implementazione corretta, validateHttpReqUrl() è stata modificata per risolvere i nomi host prima di approvare la richiesta.

Il validatore ora:

  • importa lookup da node:dns/promises
  • tratta la convalida come asincrona
  • risolve i nomi host non letterali prima di autorizzarli
  • analizza ogni indirizzo risolto
  • convalida ogni indirizzo risolto rispetto agli stessi intervalli bloccati

Questa è la correzione giusta perché cambia la decisione di fiducia da:

  • "il testo del nome host sembra ok?"

a:

  • "la destinazione effettiva si risolve in un indirizzo consentito?"

Questa è la proprietà di sicurezza che avrebbe dovuto esistere dall'inizio.

La remediation ha anche aggiunto copertura per regressioni su:

  • nomi host che si risolvono in loopback
  • nomi host che si risolvono in spazio RFC1918
  • host interni autorizzati per self-hoster
  • preservazione delle protezioni non aggirabili per destinazioni metadata e loopback

Questo è il tipo di hardening che vuoi in una vera correzione SSRF:

  • il confine è corretto
  • il comportamento previsto è documentato nel codice
  • e i test bloccano la classe

Il problema è stato risolto in Typebot 3.16.0.


Divulgazione

Questo problema è stato segnalato privatamente tramite il flusso di segnalazione di sicurezza di GitHub.

Il report includeva:

  • la causa principale in validateHttpReqUrl()
  • il percorso di esecuzione a valle in executeHttpRequest()
  • una strategia di riproduzione realistica utilizzando la risoluzione del nome host verso destinazioni loopback / private
  • e una demo autonoma per isolare la lacuna di convalida

I manutentori hanno accettato il problema, corretto la logica di convalida, e la vulnerabilità è stata successivamente pubblicata come:

CVE-2026-34207

con la correzione rilasciata in Typebot 3.16.0.


Cosa insegna realmente questo bug

La lezione chiave qui è semplice:

le decisioni di sicurezza devono essere prese sulla stessa rappresentazione che lo stack di rete utilizzerà effettivamente.

Sembra ovvio.

Ma molte protezioni SSRF falliscono proprio perché non seguono questa regola.

  • Una stringa di nome host sembra sicura.
  • Il DNS cambia ciò che significa.
  • La richiesta viene comunque inviata.

Questo è sufficiente.

Questo bug rafforza anche qualcosa di importante sulla revisione SSRF in generale:

  • il filtraggio degli IP letterali non è sufficiente
  • le blacklist dei nomi host non sono sufficienti
  • i controlli degli IP codificati non sono sufficienti

Se non risolvi e convalidi la destinazione reale, il tuo filtro SSRF è ancora incompleto.

Questo è il vero insegnamento.


Punti chiave

  • Le difese SSRF falliscono quando la convalida avviene prima della risoluzione della destinazione
  • La convalida del testo del nome host non è la stessa cosa della convalida dell'IP di destinazione
  • Le funzionalità Webhook / Richiesta HTTP sono veri confini di sicurezza
  • Un SSRF autenticato può comunque essere di alta gravità quando raggiunge metadata e servizi interni
  • Un report solido collega causa principale e impatto, non solo l'uno o l'altro
  • La correzione era corretta perché ha spostato la decisione sulla destinazione effettiva risolta

Parole finali

Questa vulnerabilità non riguardava un payload fantasioso.

Riguardava il porsi la giusta domanda sul confine.

In Typebot, il validatore SSRF controllava prima il testo del nome host. La destinazione effettiva veniva decisa successivamente dal DNS. Il client di rete seguiva l'indirizzo risolto.

Quella lacuna era il bug.

Ecco perché questo è diventato CVE-2026-34207.

Corretto in Typebot 3.16.0.

Scarica lo strumento