
Un'unica POST non autenticata all'API di gestione di Bifrost ha avviato un comando come utente del gateway
- OrcaNUOVOOrcaCyber: GLM 5.3 Flash Abliterated2026-10-2795 tok/s
- OrcaNUOVOOrcaCyber: Qwen3.8 Flash Next Abliterated2026-10-26$0.80 / $1.60 per 1M di token · 249 tok/s
- OrcaNUOVOOrcaCyber: MiMo V2.6 Flash Abliterated2026-10-26$0.80 / $1.60 per 1M di token · 86 tok/s
- MoonshotNUOVOMoonshotAI: Kimi K3.1 Pro2026-10-2455Intelligenza
- OrcaNUOVOOrcaCyber: DeepSeek V4.1 Flash Abliterated2026-10-23$0.80 / $1.60 per 1M di token · 109 tok/s
- minimaxNUOVOMiniMax: M3.1 Flash2026-10-1943Intelligenza
- OrcaNUOVOOrca: OrcaCyber Ultra 1.02026-10-17$5.00 / $10.00 per 1M di token · 51 tok/s
- deepseekNUOVODeepSeek: DeepSeek V4.1 Flash 10172026-10-1745Intelligenza
- DeepSeekNUOVODeepSeek: DeepSeek V4.1 Flash2026-10-1740Intelligenza
- OrcaOrca: OrcaCyber Zero 1.52026-10-10$3.00 / $7.50 per 1M di token · 114 tok/s
- openaiOpenAI: GPT-6.1 Sol2026-09-2952Intelligenza
- anthropicAnthropic: Claude Sonnet 5.52026-09-2856Intelligenza
- typesafeTypeSafe: Jev 1.132026-09-24$0.04 / $0.00 per 1M di token · 120 tok/s
- OpenAIOpenAI: GPT-6 Luna2026-09-2238Intelligenza
- OpenAIOpenAI: GPT-6 Sol2026-09-2248Intelligenza
- AnthropicAnthropic: Claude Opus 5.52026-09-2258Intelligenza
- xiaomiXiaomi: MiMo-V2.6-Flash2026-09-2138Intelligenza
- xiaomiXiaomi: MiMo-V2.6-Pro2026-09-2146Intelligenza
- xAIGrok 4.72026-09-2146Intelligenza
- OrcaOrca: OrcaCyber Zero 1.02026-09-17$3.00 / $7.50 per 1M di token · 191 tok/s
Il 14 settembre 2026, JFrog Security Research ha pubblicato CVE-2026-90898, una vulnerabilità di esecuzione di comandi in Bifrost — il gateway AI open source mantenuto da Maxim — e le ha assegnato un punteggio di 9,8 su 10. L'attacco consisteva in una singola richiesta HTTP. Una POST /api/mcp/client non autenticata registra un client MCP stdio, che Bifrost interpreta come un nome di programma più un elenco di argomenti e avvia immediatamente, prima di qualsiasi handshake MCP, come l'utente che esegue il gateway; nell'immagine ufficiale tale utente è appuser. Un gateway è anche il luogo in cui risiedono le chiavi provider e le chiavi virtuali di un operatore, perciò un processo in esecuzione lì raggiunge le credenziali. Ciò che rendeva anonima la richiesta era una configurazione predefinita inclusa nel prodotto: governance.auth_config.is_enabled è false e, secondo la formulazione di JFrog, «l'autenticazione disattivata significa che ogni chiamante è un amministratore locale». Nessuna fonte citata riporta che la vulnerabilità sia mai stata sfruttata. Le fonti, il livello di gravità e la valutazione di affidabilità del record stesso si trovano in l'archivio degli incidenti AI, insieme alle altre vulnerabilità documentate di gateway AI e MCP dell'ultimo anno.
Bifrost è un singolo servizio che si colloca tra un'applicazione e i modelli linguistici che essa chiama. Il suo repository lo descrive come un gateway open source con licenza Apache-2.0 che "unifica l'accesso a oltre 23 provider ... tramite un'unica API compatibile con OpenAI", con proxy MCP, chiavi virtuali, budget e bilanciamento del carico per provider tra le sue funzionalità, e aveva circa 9.150 stelle GitHub al 28 ottobre 2026. Questa combinazione è l'intera ragione per cui una shell su questo particolare host vale un punteggio critico: il processo che instrada le richieste è anche il processo che custodisce le credenziali per ogni upstream verso cui instrada. The Hacker News, nel riportare la falla il 22 settembre, ha descritto la conseguenza in modo chiaro: poiché il gateway memorizza le chiavi API per ogni provider connesso, l'esecuzione di comandi sul processo del gateway concede all'attaccante l'accesso a tali credenziali.
L'intero attacco è stato un singolo POST
L'avviso di JFrog, pubblicato con riferimento JFSA-2026-001686326, descrive un endpoint che esiste per consentire a un amministratore di aggiungere un server MCP. Un client stdio nella specifica MCP non è un URL; è un comando e i suoi argomenti, che il programma host dovrebbe avviare. Bifrost accetta quella configurazione tramite l'API di gestione e avvia il programma non appena il client viene aggiunto. Nessuna negoziazione delle capacità, nessun controllo dell'identità del server, nessun handshake deve riuscire prima — l'avviso è esplicito sul fatto che non è l'handshake ad avviare il processo.
La proof of concept nell'advisory è un breve corpo JSON inviato a un gateway con l'autenticazione lasciata al valore predefinito. Registra un client il cui comando è /bin/sh e i cui argomenti scrivono un file marker, quindi rilegge il marker. JFrog aggiunge un dettaglio operativo che conta durante la risposta agli incidenti: la richiesta HTTP può andare in timeout mentre Bifrost attende un handshake che non arriva mai, e un timeout nei log non significa che il comando non sia riuscito ad avviarsi. A quel punto il processo è già in esecuzione.
Il record CVE, assegnato da JFrog in qualità di CVE Numbering Authority, associa il difetto a CWE-306, autenticazione mancante per una funzione critica, e a CWE-284, controllo degli accessi inadeguato, e indica i due file che contengono l'handler e il relativo middleware: transports/bifrost-http/handlers/mcp.go e transports/bifrost-http/handlers/middlewares.go. Il modulo interessato è github.com/maximhq/bifrost/transports, su Linux e macOS, per tutte le versioni inferiori alla 2.1.0.
Il valore predefinito che ha reso anonima la richiesta
Niente di tutto ciò sarebbe sfruttabile senza una seconda condizione, e la seconda condizione è il default del prodotto stesso. Il middleware di autenticazione della gestione di Bifrost è controllato da governance.auth_config.is_enabled, che viene distribuito con valore false. Con questa opzione disattivata, il middleware tratta ogni chiamante come un amministratore locale — la sintesi dell'avviso stesso è che, con l'autenticazione disattivata, ogni chiamante è un amministratore locale — quindi il controllo che avrebbe bloccato la richiesta non era mai nel percorso.
La correzione, pull request #6757, è stata integrata nel progetto il 2 settembre 2026, dodici giorni prima della pubblicazione della CVE e sei giorni prima della release che la contiene. La sua descrizione è insolitamente franca riguardo alla natura del problema: la pull request chiude due primitive di accesso non autenticato nella stessa API di registrazione, non una. La prima è il client stdio. La seconda è un client MCP http o sse puntato a un indirizzo di loopback o di rete privata, che la pull request definisce una primitiva SSRF contro servizi interni, «incluso l'endpoint dei metadati cloud 169.254.169.254». Entrambe ora vengono rifiutate con HTTP 403 quando la richiesta raggiunge l'handler senza un controllo reale delle credenziali. Gli amministratori autenticati mantengono entrambe le capacità, e gli operatori possono ancora effettuare il provisioning di client stdio tramite config.json.
Quella seconda primitiva non compare nel testo della CVE. È nella patch, ed è il motivo per cui la correzione è una barriera anziché una rimozione: la funzionalità non è mai stata il bug. Lo era trattare un chiamante non autenticato come amministratore.
Dove l'API di gestione era effettivamente in ascolto
La raggiungibilità è la parte del record che le fonti descrivono nel modo più coerente, e misurano meno. L'avviso di JFrog indica come default del binario standard localhost:8080, il che confina un attaccante all'host stesso. L'avviso dello stesso team per la vulnerabilità correlata afferma che l'immagine Docker ufficiale invece si associa a 0.0.0.0, e The Hacker News lo ripete: l'immagine rende l'API di gestione raggiungibile dall'esterno del container se la porta viene pubblicata. L'avvio rapido nel README di Bifrost stesso esegue "docker run -p 8080:8080 maximhq/bifrost", e l'opzione -p di Docker pubblica una porta del container su ogni interfaccia dell'host a meno che non venga specificato un indirizzo. L'avviso GitHub per la vulnerabilità registra che il percorso segnalato è stato verificato sull'immagine pubblicata maximhq/bifrost:latest, dove una richiesta non autenticata ha avviato /bin/sh e ha scritto un marker come appuser.
Ciò che nessuna fonte fornisce è un numero. Non esiste un conteggio delle istanze Bifrost esposte a Internet, nessun risultato di scansione, nessuna telemetria e nessuna vittima. Il resoconto non riporta alcun danno reale, e questa assenza è un fatto che riguarda il modo in cui la vicenda è stata riportata, non una rassicurazione — la classe di vulnerabilità è pericolosa solo quando coincidono due condizioni, un listener esposto e un valore predefinito lasciato invariato, e nessuno ha pubblicato quanto spesso ciò sia accaduto.
Un endpoint, due difetti, una causa principale
Otto giorni prima dell'avviso MCP, il 6 settembre 2026, lo stesso team di ricerca ha pubblicato CVE-2026-86242, un secondo percorso non autenticato nello stesso processo. Scoperta da Or Peles e valutata 8.1, sfrutta POST /api/plugins: Bifrost accetta un plugin personalizzato abilitato il cui percorso è un URL HTTP, il caricatore di oggetti condivisi tratta un percorso con prefisso http come un download, scrive il corpo in un file .so temporaneo e passa quel file a plugin.Open di Go. Se il caricamento riesce, una funzione Init opzionale viene eseguita immediatamente con la configurazione dell'attaccante, come utente del gateway.
La variante di build decide cosa ottiene un attaccante. Nelle build con linking dinamico documentate dal progetto per i plugin Go personalizzati, ci si aspetta che il caricamento riesca, cosa che l'avviso definisce esecuzione di codice da remoto non autenticata. Nell'immagine Docker pubblicata con linking statico, plugin.Open fallisce con "Dynamic loading not supported", quindi la stessa richiesta degrada a server-side request forgery. Un plugin caricabile deve anche corrispondere alla versione di Go, al sistema operativo, all'architettura e al linking dell'host, il che è un vincolo reale e non una formalità. La correzione è transports/v2.0.0, tramite la pull request #5763, e l'intervallo interessato è tutto ciò che è al di sotto.
Il tranello è l'ordine delle release. La v2.0.0 corregge il percorso del plugin e non corregge il percorso MCP — The Hacker News lo afferma esplicitamente, e l'avviso MCP di JFrog conferma che la v2.0.0 consente ancora la registrazione stdio non autenticata. Un operatore che ha applicato la patch tempestivamente dopo l'avviso del 6 settembre era, su quel punto soltanto, ancora esposto finché transports/v2.1.0 non è stato distribuito l'8 settembre. Entrambi i difetti si riducono alla stessa frase in entrambi gli avvisi e nella pull request dello stesso fornitore: l'autenticazione disabilitata è l'impostazione predefinita.
Ciò che le fonti stabiliscono, e ciò che non stabiliscono
Il meccanismo, l'intervallo di versioni, la correzione e il riconoscimento sono concordati tra l'advisory, il record CVE assegnato da JFrog, la pull request e le note di rilascio del progetto stesso, e The Hacker News. Il disaccordo rimanente riguarda la gravità, ed è reale.
Il 9.8 è il punteggio di JFrog in qualità di CNA assegnatore, ed è il punteggio riportato da NVD: il record NVD elenca reefs@jfrog.com come fonte della metrica e, al 28 ottobre 2026, mostra ancora la voce nello stato "Awaiting Analysis", il che significa che NVD ha pubblicato il vettore dell'assegnatore anziché la propria analisi dello stesso. La valutazione SSVC del coordinatore CISA allegata allo stesso record, con data e ora del 14 settembre 2026, riporta sfruttamento "none", automatizzabile "yes" e impatto tecnico "total". Il modello EPSS di FIRST ha stimato la probabilità di sfruttamento nei successivi 30 giorni al 2,3 per cento al 27 ottobre 2026, nell'83º percentile tra tutte le CVE valutate, e né questa CVE né CVE-2026-86242 compaiono nel catalogo CISA Known Exploited Vulnerabilities datato 27 ottobre 2026.
Di contro, Maxim contesta la valutazione. In una dichiarazione a The Hacker News, Akshay Deo, chief technology officer e co-fondatore dell'azienda, ha affermato che il rischio pratico è inferiore a quanto suggerisce il punteggio critico, perché lo sfruttamento richiede che l'interfaccia di gestione sia raggiungibile da una rete non attendibile e che l'operatore abbia lasciato l'autenticazione non impostata; la distribuzione predefinita e documentata, ha detto, colloca il gateway all'interno di una rete privata. The Hacker News riporta che Maxim considera la vulnerabilità di bassa gravità e sta lavorando con JFrog, che ha assegnato il CVE, alla revisione della valutazione. Tale dichiarazione compare in quell'unica testata; non è stata trovata una seconda pubblicazione che citi la posizione di Maxim, e nessuna revisione era stata pubblicata al 28 ottobre 2026 — il record CVE è stato aggiornato l'ultima volta il 14 settembre e la voce NVD il 18 settembre, entrambi ancora a 9.8.
Due ulteriori lacune meritano di essere nominate anziché attenuate. Gli advisory GitHub del progetto, pubblicati il 23 settembre 2026 e che accreditano il ricercatore di JFrog come segnalatore, riportano ancora 9,8 per la falla MCP e 8,1 per quella del plugin, senza alcun segno della revisione descritta da Maxim. E gli intervalli interessati in tali advisory sono scritti rispetto alle versioni dei moduli Go — inferiori a 1.5.27 e inferiori a 1.6.3 — anziché ai tag di rilascio dei transports usati dagli advisory JFrog, quindi un operatore che confronta un documento con l'altro deve riconciliare due schemi di numerazione prima di decidere se una build è interessata.

Cosa è cambiato e cosa è stato detto agli operatori di fare
La cronologia procede all'indietro rispetto alla divulgazione, che è la parte meno intuitiva del resoconto. La pull request #6757 è stata unita il 2 settembre 2026. transports/v2.1.0, la versione che l'avviso indica come la prima contenente la correzione, è stata pubblicata l'8 settembre — sei giorni prima della pubblicazione di CVE-2026-90898 il 14 settembre. La correzione del plugin del progetto ha preceduto il proprio avviso allo stesso modo: transports/v2.0.0 è stata distribuita il 26 agosto, undici giorni prima del CVE del 6 settembre. Gli operatori che seguono le versioni anziché i feed avevano le patch prima di avere gli avvisi.
Ciò che l'aggiornamento offre è limitato e specifico. Su 2.1.0 e versioni successive, una registrazione stdio non autenticata restituisce 403 e il comando non viene avviato; gli amministratori autenticati mantengono la funzionalità e il provisioning tramite config.json continua a funzionare. La soluzione tampone dell'advisory per chi non può aggiornarsi è impostare governance.auth_config.is_enabled su true, usare credenziali amministrative robuste e tenere il listener di gestione fuori da reti non attendibili. L'istruzione di JFrog per le istanze che hanno operato esposte con l'autenticazione disabilitata non è di indagare e sperare: trattarle come compromesse e ruotare le chiavi virtuali e le credenziali del provider.
La parte più facilmente fraintendibile è l'aritmetica delle versioni. v2.0.0 non corregge questo difetto. Nemmeno la serie 1.6.x fino alla 1.6.11 contiene la correzione, e il tag più recente della serie 1.6 del progetto è transports/v1.6.11, pubblicato il 14 agosto 2026, senza alcuna serie 1.7 nel repository al 28 ottobre 2026 — quindi non esiste una release corretta all'interno di quella serie, e un operatore sulla 1.6.x deve passare alla 2.1.0 o successiva anziché attendere un backport. La linea di rilascio corrente è ben oltre quel punto: transports/v2.3.2 è stato pubblicato il 20 ottobre 2026.

Dopo la pubblicazione sono successe due cose di cui un difensore può avvalersi. Gli avvisi di sicurezza GitHub del progetto — GHSA-86gf-xh3g-rvxq per la falla MCP, con severità critica, e GHSA-2qp8-4xgm-fw6g per la falla del plugin, con severità alta — sono stati pubblicati il 23 settembre 2026, fornendo ai feed delle dipendenze e degli avvisi un secondo identificatore su cui fare corrispondenza. E il 13 ottobre 2026 un modello di rilevamento per CVE-2026-90898 è stato unito al repository pubblico nuclei-templates, il che significa che il controllo per un tentativo di registrazione non autenticata ora è qualcosa che una pipeline di scansione può eseguire, invece di qualcosa che ogni team deve scrivere.

Ciò che resta aperto è la gravità, e sarà risolta o meno dalle due organizzazioni che ne stanno ancora discutendo. La posizione di Maxim, come riportato, è che un 9.8 sovrastima una vulnerabilità che per avere rilevanza richiede un listener esposto e un valore predefinito non impostato — un'affermazione verificabile in linea di principio e non verificata pubblicamente, perché nessuno ha pubblicato quante distribuzioni soddisfacessero quelle due condizioni. La posizione di JFrog è il punteggio che ha assegnato in qualità di CNA, tuttora presente nel record CVE e in NVD. Finché una delle due pubblicherà una revisione, la lettura operativa è la stessa in entrambi i casi: la vulnerabilità è reale ed è stata verificata end to end sull'immagine container pubblicata, la correzione è stata rilasciata prima dell'avviso, la serie 1.6 non ha alcuna correzione, e qualsiasi istanza eseguita con autenticazione disabilitata su un listener raggiungibile dovrebbe essere trattata come un incidente di credenziali anziché come una patch da pianificare.
