C'è una categoria di rischio che sfugge quasi sempre agli inventari di sicurezza: il software che non doveva mai stare su internet. Non è un prodotto perimetrale mal configurato, non è un server dimenticato in DMZ. È uno strumento nato per girare su localhost, che qualcuno ha esposto per comodità e nessuno ha più tolto.
I dati di telemetria pubblicati da F5 Labs l'11 settembre 2026 mostrano cosa succede quando qualcuno se ne accorge prima di te. Nel solo mese di agosto i sensori honeynet hanno registrato 807 attacchi raggruppati per sessione e circa 32.000 eventi grezzi contro server di sviluppo Vite esposti in rete. Nei tre mesi precedenti gli eventi della stessa famiglia erano stati 1.732 in totale: un aumento di quasi venti volte.
L'obiettivo della campagna non è l'applicazione web. È l'account cloud dietro l'applicazione.
La vulnerabilità
CVE-2026-39364 è una lettura arbitraria di file non autenticata nel development server di Vite, il build tool ormai predefinito in buona parte dell'ecosistema JavaScript moderno (React, Vue, Svelte). Il punteggio CVSS è 7.5 secondo la valutazione riportata da F5 Labs, mentre altre fonti indicano 8.2; in entrambi i casi siamo nella fascia alta, ma il numero conta meno del fatto che lo sfruttamento richiede una singola richiesta HTTP GET.
Il meccanismo è semplice al punto da essere sgradevole. Per supportare il flusso di sviluppo, Vite espone una rotta interna @fs che serve file dal filesystem dell'host, e si affida a un'impostazione di deny-list — server.fs.deny — per bloccare l'accesso a elementi sensibili come i file .env, i certificati e il codice sorgente. CVE-2026-39364 permette di aggirare completamente quel filtro manipolando i parametri di query: aggiungendo ?raw, ?import&raw oppure ?import&url&inline alla richiesta, il server non applica il controllo della deny-list e restituisce il file richiesto in chiaro, con un normale HTTP 200.
Le versioni interessate sono Vite dalla 7.1.0 fino alle precedenti la 7.3.2, e il ramo 8.x prima della 8.0.5. La falla convive con una famiglia di bypass analoghi già noti — CVE-2025-30208, CVE-2025-31125, CVE-2024-45811 — che gli stessi scanner provano in parallelo: chi guarda i log vedrà firme multiple dalla stessa sorgente.
Una precisazione importante: per default Vite si lega a localhost. Il server diventa raggiungibile solo quando qualcuno passa il flag --host, imposta server.host, oppure — ed è il caso più frequente e meno consapevole — configura male il mapping delle porte di un container Docker.
Cosa cercano davvero gli attaccanti
Qui l'analisi di F5 diventa istruttiva, perché lo scanner non prova un endpoint generico: scorre una wordlist curata, costruita da qualcuno che conosce bene come sono fatti i deployment reali.
Le richieste osservate puntano a file di configurazione ambiente (.env, .env.local, .env.production, .env.staging), a credenziali AWS cercate in tutte le home directory plausibili (/root/.aws/credentials, /home/ec2-user/.aws/credentials, /home/ubuntu/.aws/credentials, /var/www/.aws/credentials, /app/.aws/credentials), ai profili Azure (.azure/credentials, .azure/accessTokens.json), e — il dettaglio che dovrebbe far riflettere chi gestisce infrastruttura — agli stati Infrastructure-as-Code: terraform.tfstate, terraform.tfvars, .terraform/terraform.tfstate, serverless.yml.
C'è poi una richiesta che tradisce competenza: /@fs/proc/self/cwd/.env. Leggere il file .env relativamente alla directory del processo in esecuzione, senza dover indovinare il percorso assoluto dell'applicazione. Non è uno script copiato da un exploit pubblico.
Due tecniche di evasione completano il quadro. Le richieste usano path traversal a doppia codifica (%252f) per aggirare le routine di normalizzazione di reverse proxy e WAF intermedi. E soprattutto gli User-Agent sono contraffatti per impersonare crawler noti: Googlebot, ClaudeBot, GPTBot, PerplexityBot, OAI-SearchBot, Amazonbot. Vengono inoltre iniettati header X-Forwarded-For e X-Real-IP falsi per aggirare ACL basate su IP e sporcare i log.
L'infrastruttura di attacco è cloud a noleggio, concentrata in range Google Cloud Platform (34.x e 35.x) distribuiti su più regioni. Gli eventi arrivano prevalentemente da Stati Uniti (17.297), Belgio (4.407), Paesi Bassi (4.011) e Singapore (2.842). Geobloccare non serve: sono provider legittimi.
Cosa significa per le aziende italiane
Questa storia riguarda più realtà di quante ne ammetteranno.
Il punto uno è chi è esposto. Non le grandi aziende con pipeline CI/CD mature, ma il tessuto intermedio: software house, web agency, system integrator, startup, reparti IT interni che hanno portato in casa lo sviluppo front-end. Gli ambienti a rischio hanno un nome ricorrente: staging, preview, demo cliente. Il container che qualcuno ha esposto per far vedere una feature al cliente, l'ambiente di preview di un branch che nessuno ha spento, il docker-compose con ports: "5173:5173" copiato da un tutorial. Nessuno di questi compare nell'inventario degli asset, perché nessuno li considera "sistemi in produzione".
Il punto due è la sproporzione tra l'esposizione e il danno. Ed è il motivo per cui questa campagna merita attenzione più di molte CVE con CVSS più alto. Il server di sviluppo esposto vale poco: contiene codice non finito e dati fittizi. Ma il file .env accanto ad esso contiene le chiavi. E le chiavi, nella quasi totalità dei casi che ho visto in ambienti reali, non sono limitate all'ambiente di sviluppo: sono lo stesso access key AWS usato anche in produzione, la stessa connection string del database, lo stesso token di un servizio di pagamento in modalità live perché "in test non funzionava". Lo stato Terraform poi è un caso a sé: contiene in chiaro segreti, password di database e la mappa completa dell'infrastruttura.
Il risultato è che una svista in un ambiente considerato irrilevante consegna l'accesso all'ambiente che conta. F5 lo dice esplicitamente: gli attaccanti stanno privilegiando l'accesso rapido all'infrastruttura del cloud provider rispetto alla compromissione applicativa.
Il punto tre è che la finestra è già passata. La campagna documentata riguarda agosto. Chi aveva un dev server Vite esposto in quelle settimane deve partire dall'assunto che le credenziali siano già state lette, non chiedersi se qualcuno le abbia prese.
Contesto normativo
Il caso tocca tre profili che vale la pena tenere distinti.
Per GDPR, la lettura di credenziali che danno accesso a database contenenti dati personali costituisce una violazione notificabile ex art. 33 anche quando l'esfiltrazione dei dati non è dimostrata: rileva la compromissione della riservatezza delle misure di sicurezza. Il termine resta 72 ore dalla conoscenza, e la conoscenza decorre da quando si accerta l'esposizione, non da quando si finisce di indagare.
Per NIS2 (D.lgs. 138/2024), chi sviluppa software per soggetti essenziali o importanti è spesso a sua volta parte della catena di fornitura vigilata. Le previsioni sulla sicurezza della supply chain rendono l'esposizione di ambienti di sviluppo un elemento contrattualmente e normativamente rilevante, non un dettaglio interno.
Il terzo profilo è contrattuale: molti contratti di sviluppo italiani contengono clausole sulla protezione del codice sorgente e sulla riservatezza. Un dev server esposto che serve @fs significa anche sorgente leggibile da chiunque.
Cosa fare subito
- Aggiornare Vite alla 7.3.2, alla 8.0.5 o alle ultime release patchate dei rami 4.5.x, 5.4.x e 6.x. Verificare anche i progetti fermi: una repo non toccata da mesi può avere un ambiente di preview ancora attivo.
- Cercare l'esposizione, non aspettarla. Scansionare i propri range IP pubblici alla ricerca della porta 5173/TCP e delle altre porte di sviluppo comuni (3000, 4200, 8080). Verificare i mapping nei
docker-compose.ymle le regole di ingress su Kubernetes e sui security group cloud. - Ruotare i segreti, se c'è stata esposizione. Non è un'opzione prudenziale, è la conseguenza logica: access key e secret AWS, token Azure, stringhe di connessione ai database, chiavi API di terze parti, contenuto degli stati Terraform. E ruotarli anche se non ci sono evidenze di accesso: i log del dev server, se mai sono esistiti, non bastano a escluderlo.
- Bloccare il pattern al WAF: negare qualunque richiesta che contenga il segmento di percorso
/@fs/. È una regola a impatto nullo sul traffico legittimo verso un'applicazione in produzione. - Smettere di fidarsi degli User-Agent. Se esistono regole che esentano dai controlli il traffico dichiarato come Googlebot o come crawler AI, verificare l'origine tramite reverse DNS prima di applicare l'esenzione. Questa campagna esiste proprio perché quelle eccezioni sono diffuse.
- Separare per davvero i segreti per ambiente. Chiavi di sviluppo distinte da quelle di produzione, con permessi minimi e scadenza breve. È l'unica misura che rende un dev server esposto un incidente noioso invece che un incidente grave.
- Spostare i segreti fuori dai file. Vault, AWS Secrets Manager, Azure Key Vault: se non c'è un
.envsul filesystem, non c'è nulla da leggere. Vale anche per gli stati Terraform, che vanno tenuti in backend remoti cifrati e mai nella working directory di un server raggiungibile. - Aggiungere gli ambienti effimeri all'inventario. Preview, staging e demo sono asset. Se non hanno un proprietario e una data di spegnimento, diventeranno il punto di ingresso.
La lezione operativa è che la superficie d'attacco di un'organizzazione non coincide con ciò che l'organizzazione considera produzione. Coincide con ciò che risponde su internet.