Il vibe coding non è sicuro per impostazione predefinita, ma nemmeno insicuro per natura: una web app generata dall'IA è sicura quanto lo sono i controlli che qualcuno ha fatto su di essa. Nelle app create con i creatori di app con IA ricompare sempre lo stesso pugno di falle: dati leggibili da chiunque, chiavi segrete nel browser, regole applicate solo nell'interfaccia. Ognuna può essere verificata da chi non è sviluppatore in pochi minuti, e per ognuna esiste un prompt di follow-up che la corregge.
Questa checklist è per fondatori, freelance e piccoli team che stanno per dare accesso al primo utente reale a un'app creata con un creatore di app con IA. Se il metodo è nuovo per voi, partite dalla nostra guida al vibe coding. Se la vostra app usa Supabase, i dettagli sul lato database sono nella nostra guida alla row level security di Supabase.
Perché le app create con l'IA falliscono sempre allo stesso modo
Un creatore di app con IA punta a un'app che funzioni a schermo, e una schermata che funziona non dice nulla su chi altro possa raggiungere i dati che ci stanno dietro. Quando chiedete "una dashboard in cui ogni cliente vede le proprie fatture", il modello costruisce prima la schermata. Che il database rifiuti di restituire le fatture degli altri clienti è un lavoro a parte, e viene fatto solo se il prompt o le impostazioni predefinite del creatore lo richiedono.
Un esempio pubblico mostra la forma del problema. Nel 2025 è stato pubblicato un record di vulnerabilità (CVE-2025-48757) che descriveva policy di row level security insufficienti in siti generati con Lovable, fino al 15 aprile 2025, che permettevano a visitatori non autenticati di leggere o scrivere nelle tabelle. La scheda della National Vulnerability Database nota anche che il fornitore contesta la segnalazione e afferma che ogni cliente è responsabile della protezione dei dati della propria applicazione. Entrambe le affermazioni portano alla stessa conclusione pratica: chi pubblica l'app deve verificarne le regole di accesso, qualunque sia lo strumento che l'ha scritta.
Le sette falle in sintesi
La maggior parte di queste falle corrisponde alla OWASP Top 10, l'elenco di riferimento dei rischi per le applicazioni web, nell'edizione 2025. La corrispondenza qui sotto usa i nomi delle categorie di quell'elenco.
| Falla | Cosa fa un attaccante | Categoria OWASP 2025 | Il vostro test di 10 minuti |
|---|---|---|---|
| 1. Row level security assente | Legge o modifica qualsiasi tabella tramite l'API pubblica | A01 Broken Access Control | Due account, confrontare cosa vede ciascuno |
| 2. Chiavi segrete nel frontend | Copia la chiave dal browser e spende i vostri soldi | A02 Security Misconfiguration | Scheda Rete e sorgente della pagina |
| 3. Regole solo nell'interfaccia | Chiama direttamente l'API e salta il pulsante nascosto | A01 Broken Access Control | Rieseguire una richiesta con il ruolo sbagliato |
| 4. Pagine admin raggiungibili via URL | Digita /admin nella barra degli indirizzi | A01 Broken Access Control | Aprire gli URL admin da disconnessi e come utente normale |
| 5. Upload di file non validati | Carica file enormi, sbagliati o pubblici | A06 Insecure Design | Caricare un file sbagliato, aprire il suo link da disconnessi |
| 6. Dipendenze obsolete | Sfrutta una falla nota di un pacchetto vecchio | A03 Software Supply Chain Failures | Eseguire il comando di audit dei pacchetti |
| 7. Nessun rate limit | Inonda le registrazioni o svuota i vostri crediti IA | A06 Insecure Design | Ripetere una richiesta 50 volte e vedere cosa succede |
1. Row level security assente
Con un backend Supabase, il browser parla con il database tramite un'API pubblica, quindi l'unica cosa che separa un visitatore dalle vostre tabelle è la row level security (RLS): regole associate a ogni tabella che dicono quali righe un utente può leggere o scrivere. Una tabella senza RLS attiva può essere letta da chiunque abbia la chiave pubblica, e quella chiave sta nel browser per costruzione. Supabase spiega il meccanismo nella sua documentazione sulla row level security.
Il test richiede cinque minuti. Create due account, A e B, con email diverse. Come A, create un record (una fattura, una nota, un progetto). Uscite, accedete come B e cercate il record di A in ogni elenco e ricerca. Poi aprite gli strumenti per sviluppatori del browser, andate alla scheda Rete (Network), ricaricate la pagina, cliccate una richiesta al database e leggete la risposta: deve contenere solo le righe di B. Infine uscite e ricaricate la stessa pagina: le richieste devono restituire niente oppure un errore.
Prompt di follow-up: "Elenca tutte le tabelle del database indicando se la row level security è attiva e quali policy si applicano. Attiva la RLS su ogni tabella che ne è priva e scrivi policy in modo che un utente possa fare select, insert, update e delete solo sulle righe in cui user_id è uguale al suo id. Mostrami le policy e spiega ogni tabella che hai lasciato pubblica di proposito."
2. Chiavi segrete nel frontend
Tutto ciò che viene inviato al browser è pubblico, comprese tutte le chiavi che si trovano nel sorgente della pagina. Alcune chiavi sono fatte per essere pubbliche (la chiave pubblica di Supabase, protetta dalla RLS). Altre no: le chiavi segrete dei pagamenti, le chiavi dei provider di IA, le chiavi dei servizi di email, la chiave service role del database. Un visitatore che ne copia una può inviare email a vostro nome o eseguire richieste IA a vostre spese.
Per verificarlo, aprite l'app pubblicata, aprite gli strumenti per sviluppatori, andate alle schede Rete e Sorgenti (Sources) e cercate i primi caratteri di ogni segreto che usate (per esempio "sk_" per una chiave di pagamento) e il nome di qualsiasi provider. Cercate anche nel codice del progetto e nel suo repository GitHub se lo esportate. Un segreto in un repository pubblico conta come trapelato anche dopo averlo eliminato.
Prompt di follow-up: "Cerca in tutto il progetto chiavi API, token e segreti nel codice client. Sposta ogni chiamata che richiede un segreto in una edge function lato server, leggi la chiave dalle variabili d'ambiente e non usare mai la chiave service role nel browser. Elenca cosa hai spostato." Se un segreto è stato esposto, ruotatelo presso il provider: eliminare il codice non annulla la chiave.
3. Autorizzazione controllata solo nell'interfaccia
Nascondere un pulsante è una scelta di design, non un permesso. Se il pulsante di eliminazione è nascosto per il ruolo "viewer" ma il database accetta comunque la richiesta di eliminazione, qualsiasi viewer con gli strumenti per sviluppatori può inviarla. Le regole vanno applicate dove vivono i dati, con l'interfaccia che si limita a rifletterle.
Per verificarlo, accedete con il ruolo più basso, eseguite un'azione consentita come leggere e, nella scheda Rete, copiate quella richiesta (clic destro, "Copy as fetch"). Modificatela in qualcosa di vietato, come cambiare l'id di un altro record o un campo del ruolo, ed eseguitela nella console. Se riesce, la regola esiste solo nell'interfaccia. Controllate anche che un utente non possa modificare il proprio campo ruolo o piano.
Prompt di follow-up: "Per ogni ruolo, elenca le azioni che può eseguire su ciascuna tabella. Applicale con policy del database, non solo nell'interfaccia. Impedisci agli utenti di aggiornare le proprie colonne role, plan o user_id."
4. Pagine admin raggiungibili via URL
Una pagina admin che semplicemente non è linkata nel menu resta raggiungibile da chiunque indovini l'indirizzo. La pagina deve controllare il ruolo prima di mostrare qualsiasi cosa, e i dati che ci stanno dietro devono essere protetti dalle policy del punto 1.
Per verificarlo, elencate le vostre rotte admin (/admin, /settings/users, /dashboard/all). Apritele una per una in una finestra privata da disconnessi, poi accedendo come utente normale. Dovreste finire su una pagina di login o su una pagina "accesso negato", e la scheda Rete non deve mostrare dati admin in nessuna risposta.
Prompt di follow-up: "Proteggi ogni rotta admin in modo che solo gli utenti con il ruolo admin possano aprirla, reindirizza tutti gli altri e assicurati che anche le query dei dati in quelle pagine falliscano per i non admin."
5. Upload di file senza validazione
Un campo di upload che accetta qualsiasi file, di qualsiasi dimensione, in una cartella pubblica permette a degli estranei di ospitare contenuti sul vostro dominio e di riempire il vostro spazio di archiviazione. I documenti privati (contratti, CV, fatture) non devono essere leggibili tramite un link indovinabile.
Per verificarlo, caricate un file di tipo sbagliato (un eseguibile rinominato .jpg) e un file molto grande. Poi copiate il link di un documento privato caricato e apritelo in una finestra privata. Se si apre, il bucket è pubblico.
Prompt di follow-up: "Limita gli upload a questi tipi di file: [elenco] e a una dimensione massima di [x MB], verificate al caricamento. Rendi privato il bucket, aggiungi policy di storage in modo che un utente possa leggere solo i propri file e servi i file tramite link firmati che scadono."
6. Dipendenze obsolete
Un'app è fatta di centinaia di pacchetti open source, e un pacchetto con una falla nota è una porta d'ingresso già pronta. OWASP lo raggruppa sotto i software supply chain failures. L'IA può anche scegliere una versione vecchia di un pacchetto che ha imparato da esempi più datati.
Il test è un solo comando nel progetto esportato: "npm audit" elenca le vulnerabilità note nei pacchetti installati. Se non potete eseguirlo, chiedete all'IA di fare una verifica equivalente. Programmatelo di nuovo prima di ogni rilascio importante.
Prompt di follow-up: "Controlla le dipendenze alla ricerca di vulnerabilità note e versioni major obsolete. Aggiorna quelle che hanno una correzione, evita le modifiche che rompono la compatibilità ed elenca cosa non hai potuto aggiornare e perché. Rimuovi i pacchetti che l'app non usa."
7. Nessun rate limit su registrazione ed endpoint IA
Senza limiti, uno script può creare migliaia di account falsi o chiamare il vostro endpoint IA finché a crescere non è la fattura del provider invece del numero di utenti. Due punti contano più degli altri: la registrazione (e la reimpostazione della password, che invia email) e qualsiasi funzione che chiama un'API a pagamento.
Per verificarlo, inviate più volte di seguito la stessa richiesta di registrazione o IA dagli strumenti per sviluppatori o da un semplice script e osservate se qualcosa la rallenta o la blocca. Controllate anche che gli endpoint IA richiedano un utente connesso e che un utente non possa inviare un prompt da 10 MB.
Prompt di follow-up: "Richiedi il login su ogni edge function che chiama un'API a pagamento, limita ogni utente a [n] chiamate all'ora, imposta un tetto alla dimensione dell'input e restituisci un errore chiaro quando il limite è raggiunto. Attiva la conferma via email e un captcha sulla registrazione."
Dati personali e GDPR
Se i vostri utenti sono in Europa, l'app contiene dati personali e ne siete responsabili, qualunque sia lo strumento che l'ha creata. Le falle di sicurezza qui sopra sono anche il modo abituale in cui i dati personali trapelano. Oltre a quelle, verificate le basi: un'informativa sulla privacy che corrisponda a ciò che l'app raccoglie davvero, un modo per eliminare l'account e i dati di un utente, e nessun dato personale nei log o negli strumenti di analisi che non intendevate inviare. La nostra guida a GDPR e app no-code con IA tratta l'aspetto legale più in dettaglio.
Prompt di follow-up: "Aggiungi una funzione di eliminazione dell'account che rimuova le righe e i file dell'utente, elenca ogni campo di dati personali che conserviamo e perché, e assicurati che nessun dato personale venga scritto nei log."
Cosa fa Cadrant per impostazione predefinita, e cosa no
Cadrant, il nostro creatore, genera app React con un backend Supabase nel vostro account Supabase. Per impostazione predefinita, l'IA scrive le migrazioni del database con policy di row level security sulle tabelle per utente, comprese le policy di storage, e può ispezionare lo schema e le policy attuali prima di modificarli. Le chiavi segrete non vengono messe nel codice client: le integrazioni come Stripe, OpenAI o i provider di email passano da edge function di Supabase, con i segreti conservati come variabili d'ambiente. La nostra documentazione lo descrive nelle pagine su edge function e variabili d'ambiente.
Le impostazioni predefinite riducono il numero di errori; non sostituiscono il test. Un prompt può ancora chiedere una tabella pubblica, un modello può ancora dimenticare una policy su una tabella che aggiungete in seguito, e nessun creatore rivede al posto vostro le vostre regole di business. Eseguite il test con due account dopo ogni modifica importante, qualunque strumento usiate.
Una checklist prima del lancio
Quando l'app gestisce pagamenti, dati sanitari o altre informazioni regolamentate, una revisione una tantum da parte di un professionista della sicurezza vale quello che costa: questa checklist individua le falle comuni, non tutte le falle. Per la parte di creazione, vedete la nostra pagina del creatore di app con IA.