In breve
Il codice che scrive un’IA di solito funziona. Ciò che fallisce è chi può raggiungere i dati. In un audit del 2026 su 200 app vibe-coded in produzione, il 91% aveva almeno una vulnerabilità e il controllo di accesso difettoso era il gruppo più grande. Ho riprodotto cinque di queste falle di accesso su uno stack Supabase locale: con la sola chiave pubblica, una tabella senza RLS, una policy sempre vera, una vista e una secret key trapelata hanno restituito ciascuna tutte e 3 le righe su 3. Controlli prima la sua app su questi punti.
Sono Denys, ingegnere full-stack e di IA. Sistemo app costruite con Lovable, Bolt, Cursor o Claude Code, e la maggior parte gira su Supabase. Questo articolo raccoglie cosa dice la ricerca pubblicata sulla sicurezza del vibe coding e cosa ho visto ricostruendo apposta gli errori più comuni.
Quali sono i rischi di sicurezza del vibe coding?
Il rischio principale è il controllo di accesso difettoso: dati che qualsiasi visitatore può leggere o modificare perché la regola che dovrebbe fermarlo manca, è troppo larga o viene aggirata. Seguono l’injection e l’autenticazione debole. Tre studi indipendenti vanno nella stessa direzione:
| Studio | Cosa è stato testato | Cosa ha trovato |
|---|---|---|
| Deng, Fan e Meng, arXiv 2606.23130, giugno 2026 | 200 app in produzione costruite con Claude Code e Lovable, verificate a mano e con agenti | 182 app su 200 (91%) avevano almeno una vulnerabilità; il 65,77% dei 1.186 rilievi era Critical o High; il controllo di accesso difettoso era la categoria più grande, nel 64% delle app |
| Escape, ottobre 2025 | 5.600 app pubbliche di Lovable, Base44, Create.xyz e altri, scansione passiva | Oltre 2.000 vulnerabilità ad alto impatto, oltre 400 segreti esposti, 175 casi di dati personali esposti; la causa principale erano permessi configurati male, soprattutto la RLS di Supabase |
| Veracode GenAI Code Security Report, 2025 e 2026 | 80 compiti di programmazione assegnati a oltre 100 modelli | Solo il 55% dei compiti ha prodotto codice sicuro nel 2025; il tasso medio di successo era del 56% nel 2026, invariato per dimensione dei modelli e anno |
Gli studi misurano cose diverse, quindi le percentuali non si sommano in un unico numero. Ciò che condividono è la forma: il codice funziona e le falle stanno al confine di fiducia.
Quali falle ho riprodotto?
Ho creato una tabella orders con tre righe di clienti finti su uno stack Supabase locale (CLI 2.109.1, Postgres 17.6, PostgREST 14.14). Poi ho chiamato la Data API come fa un browser, con la publishable key che ogni frontend Supabase pubblica, cambiando una sola cosa alla volta.
| Configurazione | Cosa ha ottenuto la chiave pubblica | Perché |
|---|---|---|
| Tabella senza RLS | Tutte e 3 le righe, e un insert ha risposto 201 Created |
I grant predefiniti lasciano leggere e scrivere anon, e nulla filtra le righe |
| RLS attiva, nessuna policy | [], un elenco vuoto |
La RLS senza policy nega tutto ad anon e authenticated |
Policy using (true) |
Tutte e 3 le righe | La policy esiste, quindi la tabella sembra protetta, ma consente ogni riga |
| Vista sulla tabella protetta | Tutte e 3 le righe | Una vista gira con i diritti del suo proprietario, a meno che abbia security_invoker = true; con quell’opzione si ottiene [] |
| Secret key nel codice del frontend | Tutte e 3 le righe | La secret key corrisponde a service_role, che ha BYPASSRLS |
La seconda riga è il momento pericoloso. La RLS è attiva e l’app mostra un elenco vuoto, quindi sembra rotta. Il prompt più rapido che la “ripara” è una policy che consente tutto, cioè la terza riga. Questo ciclo, un errore e poi una correzione che allarga l’accesso, è lo schema che incontro più spesso nelle app vibe-coded, ed è per questo che “la RLS è attiva” da sola dice poco.
Perché il codice scritto dall’IA fallisce sul controllo di accesso?
Un agente viene premiato per il codice che funziona. Un elenco vuoto o un 401 sembra un bug, e la correzione che lo fa sparire è spesso quella che apre l’accesso. Lo studio arXiv ricollega i suoi 1.186 rilievi a otto modalità di errore ricorrenti, raggruppate come difetti di memoria, di obiettivo e di conoscenza degli agenti, e ha trovato che un prompt migliore riduceva il numero di falle ma non le eliminava.
Il secondo motivo è l’architettura. Un’app Lovable o Bolt di solito non ha un backend proprio: il browser parla direttamente al database tramite la Data API. Ogni regola che protegge i dati dei clienti deve vivere in Postgres, come grant, policy e funzioni, e nulla di tutto questo è visibile nell’anteprima dell’app, dove ha eseguito l’accesso come proprietario. Supabase cambia qui un’impostazione predefinita: dal 30 ottobre 2026 le nuove tabelle dei progetti esistenti non ricevono più automaticamente grant per la Data API. Sul mio stack una tabella senza il grant ha risposto 42501 permission denied con un suggerimento che nomina il GRANT mancante. Questo ferma la prima riga della tabella qui sopra per le nuove tabelle, ma non le altre quattro, e non le tabelle già esistenti.
Cos’altro va storto fuori dal database?
Gli stessi studi elencano rischi che non c’entrano con la RLS:
- Segreti nel bundle. Escape ha trovato oltre 400 segreti esposti, comprese chiavi OpenAI e chiavi di amministrazione dei pagamenti. Tutto ciò che viene consegnato al browser è pubblico.
- Guardie delle rotte solo in React. Una pagina che reindirizza gli utenti non autenticati ha comunque dietro un’API che risponde a chiunque.
- Rate limit che non scattano mai. Su un progetto Supabase ospitato che ho sondato, un contatore tenuto nella memoria di una edge function si azzerava a ogni richiesta. L’ho descritto nella mia checklist di sicurezza per le app Lovable.
- Librerie vecchie. Escape ha contato 254 istanze di librerie JavaScript vulnerabili negli asset pubblici, spesso ereditate dai template.
Come si controlla un’app vibe-coded?
- Apra l’app, poi DevTools → Network, e trovi le richieste a
/rest/v1/. Ne copi una come cURL, tolga l’headerAuthorization, tengaapikeye la esegua. Se tornano dati, tornano per chiunque. - Cerchi nel JavaScript compilato
sb_secret_eservice_role. Un risultato è una chiave da ruotare oggi. - Esegua il Controllo sicurezza Supabase gratuito. Legge il catalogo del progetto e segnala, tra le sue 46 regole, “RLS disattivato su tabelle esposte”, “Policy che consentono ogni riga”, “View che aggirano RLS” e “Privilegi predefiniti che aprono i nuovi oggetti all’API”: le prime quattro righe della tabella qui sopra.
- Testi con due utenti in due aziende, l’unico test che uno scanner non può fare al posto suo. Come lo faccio è nella checklist Lovable, e come testare la Supabase RLS mostra il metodo su un’app in produzione con una schermata dei permessi.
curl 'https://<project>.supabase.co/rest/v1/orders?select=*' \
-H 'apikey: <the publishable key from your page>'
Cosa questo non dimostra
La mia riproduzione è una tabella su uno stack locale, costruita per mostrare ogni meccanismo, non una scansione di app reali. I numeri di diffusione vengono dai tre studi, ciascuno con il suo campione e il suo metodo, linkati sopra. E un risultato pulito su questi cinque controlli non rende sicura un’app: i bug di logica, come una guardia che lascia passare un valore mancante, richiedono test propri. Uno è in un NULL che ha saltato un controllo dei permessi.
Ha costruito la sua app con uno strumento di IA?
Mi confronto volentieri su cosa controllare per primo. Nessuna vendita.
Mi contatti