Database esposto nel vibe coding: come evitarlo prima del go-live
Un database può essere esposto anche quando l’app sembra funzionare bene. La UI mostra solo i dati corretti, il login funziona, le API rispondono, il deploy passa e il founder può fare una demo convincente. Il rischio nasce altrove: una connection string nel repository, un database raggiungibile da internet, regole troppo permissive, un backup pubblico, un utente con privilegi eccessivi o un endpoint generato dall’AI che restituisce più dati del previsto.
Nel vibe coding, il database arriva presto. Strumenti come Lovable, Bolt.new, Replit Agent, Cursor, Copilot, Codex e Claude Code aiutano a collegare tabelle, storage, autenticazione, API, dashboard e deploy in tempi molto brevi. Questa velocità è utile, ma spinge spesso verso configurazioni che fanno funzionare subito l’MVP e rimandano l’hardening. Per founder, PM e developer junior, la domanda prima della beta non è solo “il database risponde?”, ma chi può raggiungerlo, con quali credenziali, da quali ambienti, attraverso quali API, con quali regole, quali backup, quali export e quali dati reali.
Database esposto non significa solo SQL injection
Quando si parla di database esposto, molti pensano subito a SQL injection. È un rischio importante, ma nelle app create con AI l’esposizione nasce spesso prima: configurazione, credenziali, permessi, rete, storage, backup e API. Un database può essere protetto contro injection e comunque esporre dati perché una policy è aperta, una chiave è nel client o un dump è finito in un bucket.
Gli errori più comuni sono pratici: file .env committati, connection string nei log, RLS disabilitata, Firebase Security Rules permissive, MongoDB accessibile da IP troppo ampi, Postgres con accesso pubblico non necessario, database di staging con dati reali, service key usate dal frontend, backup scaricabili, export CSV non protetti e route di debug lasciate online. Il problema non è il database scelto — PostgreSQL, Supabase, Firebase, MongoDB Atlas, RDS, Cloud SQL, PlanetScale, Neon, Pinecone, pgvector o un database self-hosted possono essere usati in modo sicuro — ma pubblicare un’app prima di aver verificato come il dato entra, viene letto, viene copiato e può uscire.
Connection string, file .env e credenziali nel posto sbagliato
La prima esposizione è spesso una stringa di connessione. Durante lo sviluppo con AI, il developer incolla un database URL in chat, l’agente genera un file .env, un esempio di deploy finisce nel README, un log stampa la configurazione o una variabile privata viene messa nel frontend per risolvere un errore. Una connection string può contenere host, database, utente, password, parametri TLS e privilegi: se finisce in Git, prompt, ticket, log, artifact o bundle, non basta rimuoverla dal file, va ruotata. Anche una credenziale di staging può essere critica se quello staging contiene dati reali o ha accesso a risorse condivise.
Prima del go-live, è necessario cercare database URL, password, service key, file .env, file .pem, dump, backup e credenziali CLI in repository, history Git, branch, tag, log CI/CD, prompt, issue e artifact. Il passo successivo è separare le chiavi di sviluppo, staging e produzione: una chiave usata dall’agente o in demo non dovrebbe mai leggere il database reale.
Database raggiungibile da internet
Molti database cloud nascono con un endpoint raggiungibile. A volte è necessario; spesso è solo comodo. Se il database accetta connessioni da IP ampi, da tutto internet o da reti non controllate, password e segreti diventano l’unica barriera, il che è insufficiente per un ambiente di produzione. Per un MVP, questo succede quando il team deve far parlare rapidamente app, dashboard, tool locale e deploy.
È importante controllare network access, IP allowlist, security group, firewall, VPC, private networking e regole di connessione. In PostgreSQL self-hosted, parametri come listen_addresses e pg_hba.conf decidono da dove si può entrare; in MongoDB Atlas, l’IP access list è un controllo chiave; in ambienti cloud, security group e route di rete devono essere coerenti con l’architettura reale. Un database di produzione non dovrebbe essere accessibile da ogni ambiente temporaneo, preview deploy o laptop personale senza necessità: se serve accesso amministrativo, è preferibile usare canali controllati come bastion, VPN, private endpoint o accesso temporaneo.
Regole permissive in Supabase, Firebase e BaaS
Le piattaforme BaaS accelerano molto lo sviluppo, ma la sicurezza dipende dalle regole. Supabase richiede Row Level Security e policy coerenti per isolare utenti e tenant; Firebase usa Security Rules per Firestore, Realtime Database e Storage. Se l’AI genera una regola aperta per far passare la demo, il provider resta robusto ma il dato può uscire.
In Supabase, una tabella con dati privati non dovrebbe avere policy generiche o RLS assente. La anon key può stare nel client solo se RLS e policy limitano davvero ciò che il client può leggere e scrivere, mentre la service role key deve restare fuori dal frontend, dai log e dal repository. In Firebase, regole come allow read, write: if true o controlli basati solo su request.auth != null possono essere troppo ampi. Prima del go-live, è utile testare lettura e scrittura con utenti diversi, dati di tenant diversi, token assente, token scaduto e richieste dirette, senza fidarsi del fatto che la UI mostri solo i record corretti.
Utenti database troppo privilegiati
Un’app non dovrebbe collegarsi al database con un utente amministrativo se non serve. Nel vibe coding, però, l’AI può suggerire la credenziale che “risolve” l’errore di permessi — superuser, owner del database, service role, account con accesso a tutte le tabelle, chiave con privilegi globali — rendendo ogni bug più costoso. Se l’app ha SQL injection, SSRF, RCE, leak di log o un endpoint abusabile, l’attaccante eredita privilegi troppo ampi. Anche senza attacco esterno, un agente AI con terminale o tool database può eseguire operazioni che non dovrebbero essere nel suo perimetro.
Il controllo corretto è il principio di least privilege. Significa usare utenti separati per applicazione, migration, job di manutenzione, lettura analytics e amministrazione, limitando permessi a tabelle, schema e operazioni necessarie, ed evitare utenti runtime con DROP, ALTER, privilegi globali o accesso a dati fuori perimetro.
Backup, dump ed export esposti
Spesso il database operativo è più protetto delle sue copie. Dump SQL, export CSV, snapshot, backup automatici, file temporanei, report, artifact di pipeline e cartelle di supporto possono contenere l’intero patrimonio dati. In un MVP, questi file vengono creati per debug, migrazione, demo o test e poi dimenticati in bucket cloud, storage BaaS, repository, ambienti di staging, laptop, sistemi di ticketing, email, CI/CD, container image o cartelle temporanee.
Backup e dump devono avere accessi limitati, cifratura dove appropriata, retention definita, logging degli accessi e separazione dagli asset pubblici. Un dump reale in staging può essere più esposto della produzione, e un export CSV generato da una route admin può essere scaricabile senza controlli adeguati. Se una copia contiene dati reali, va trattata come produzione.
API generate che espongono il database
Anche quando il database non è direttamente pubblico, le API possono esporlo. Un agente può generare endpoint CRUD, route admin, funzioni di ricerca, export, debug, filtri, report o dashboard che leggono dati senza autorizzazione sufficiente, rendendo di fatto l’endpoint il database esposto.
Esempi frequenti: /api/users restituisce tutti gli utenti, /api/orders?user_id=... accetta ID dal client senza verifica, /api/export produce un CSV completo, /api/debug/db resta attivo in produzione, una route admin controlla solo il login, una ricerca globale ignora tenant e ruoli, una funzione serverless usa la service key e non filtra i risultati. Prima del go-live, è necessario fare inventario delle route che leggono dal database e provare chiamate dirette, parametri manipolati, token mancanti, ruolo basso, tenant diverso e metodi HTTP non previsti. Se un endpoint restituisce dati che la UI non mostrerebbe, il database è esposto attraverso l’app.
Storage, bucket e metadati collegati al database
Molte app associano record database a file: documenti, immagini, allegati, fatture, avatar, contratti, report, esportazioni, dataset. Se il database contiene solo il path ma il bucket è pubblico, la protezione del record non basta; se l’URL è prevedibile, un utente può scaricare file altrui anche senza query al database.
È necessario verificare bucket, path, URL firmati, durata dei link, policy per utente o tenant, anteprime, thumbnail, testo estratto e metadati. Un file può essere privato ma avere anteprima pubblica, un nome file può rivelare informazioni cliente e un export può essere salvato nello storage e restare accessibile dopo la scadenza prevista. Il test pratico è semplice: caricare file con due utenti diversi, poi provare download e delete incrociati cambiando ID, path o nome file. Se l’app usa Supabase Storage, Firebase Storage, S3 o simili, il controllo deve includere sia le policy dello storage sia la logica applicativa.
Staging, preview e dati reali
Uno degli errori più comuni è usare dati reali fuori dalla produzione. Il team copia un dump per debug, collega un preview deploy al database reale, usa le stesse chiavi in staging, importa clienti per una demo o testa un agente su dati veri. Questi ambienti di solito hanno meno controlli, più persone con accesso e log più verbosi.
La separazione dev/staging/prod deve riguardare database, storage, chiavi, utenti, callback, backup e strumenti di osservabilità. Se servono dati realistici, è preferibile usare dataset sintetici, masking o subset minimizzati, evitando che preview URL, branch temporanei o ambienti generati dall’AI puntino al database reale. Quando un database di staging contiene dati reali, va trattato come produzione: accessi limitati, backup protetti, logging, retention, patching e controllo delle credenziali.
Vector database, RAG e leakage dei documenti
Le app AI che usano RAG aggiungono un’altra forma di database: vector store, embedding store, document index. ChromaDB, Pinecone, pgvector e altri sistemi possono contenere frammenti di documenti, ticket, email, contratti, manuali, knowledge base e dati cliente. Se il retrieval non applica autorizzazione, un utente può ricevere contesto che appartiene ad altri.
La sicurezza del vector database non si limita al database engine, ma richiede di controllare cosa viene indicizzato, con quali metadati, in quale namespace o tenant, chi può recuperarlo, quali filtri vengono applicati prima del retrieval e quali documenti finiscono nei log o nel prompt del modello. Per app multi-tenant, è necessario separare namespace o applicare filtri autorizzativi robusti, loggare quali documenti vengono recuperati e prevedere cancellazione e reindicizzazione quando un utente elimina dati o cambia permessi. Se il modello riceve documenti non autorizzati, la risposta può già aver esposto il dato.
Agenti AI con accesso al database
Quando un agente può usare terminale, MCP, tool SQL, dashboard cloud o credenziali runtime, il database diventa parte del suo perimetro operativo. Il rischio non è solo che l’agente generi codice sbagliato: può eseguire query, modificare dati, lanciare migration, leggere tabelle o stampare risultati in chat e log.
Non dare a un agente credenziali di produzione se non è strettamente necessario. È preferibile usare database sandbox, dati sintetici, utenti read-only, permessi temporanei e approvazione per comandi distruttivi. Se l’agente deve generare migration, è opportuno fare review prima di applicarle; se deve interrogare dati, è necessario limitare tabelle e righe disponibili. Per agenti collegati via MCP o tool esterni, occorre mappare quali azioni sono possibili — leggere, scrivere, cancellare, esportare, creare utenti, modificare schema, accedere a secret manager — e applicare il principio di least privilege: l’agente deve avere solo ciò che serve per il task, non tutto ciò che è comodo.
Cosa verificare prima della beta
Prima di aprire una beta o importare dati reali, è utile preparare un inventario del dato: quali database esistono, quali ambienti li usano, quali utenti e chiavi accedono, quali API leggono o scrivono, quali backup sono attivi, quali bucket contengono file collegati ai record, quali agenti o pipeline hanno credenziali.
Poi è necessario eseguire test pratici: secret scanning su repository e history, controllo rete, verifica policy, accesso con utente a privilegi minimi, test API su export e route di debug, download file con utenti diversi, ricerca di dump e backup in artifact, controllo staging e preview. Questi passaggi trovano problemi che una demo non mostra.
Segnali che il database è già troppo esposto
Alcuni segnali meritano attenzione immediata anche se non si è ancora trovata una violazione: un file .env committato, una connection string in un log, un database che accetta connessioni da IP non riconosciuti, un backup in un bucket condiviso, una dashboard admin raggiungibile fuori dalla rete prevista, un preview deployment con dati reali, un export CSV con più colonne del necessario.
Altri segnali emergono dai comportamenti dell’app: una query di lista restituisce record di tutti gli utenti e poi la UI filtra lato client, un endpoint accetta limit=100000 e produce export completi, una funzione di ricerca restituisce risultati cross-tenant, un utente database usato dall’app può leggere tabelle che nessuna feature usa, un agente AI può eseguire query su produzione per aiutare il debug. Questi segnali non sono tutti incidenti, ma indicano che il perimetro dati non è governato. Prima di collegare utenti reali, vale la pena fermarsi e ricostruire il percorso del dato: ingresso, query, API, storage, log, backup, export e cancellazione.
Cosa correggere prima e cosa pianificare
La priorità va data a tutto ciò che consente accesso diretto o copia massiva dei dati. Connection string di produzione esposte, database raggiungibile da reti non previste, backup pubblici, service key nel frontend, utenti database amministrativi usati dall’app, export senza autorizzazione e regole aperte su dati privati devono essere corretti prima del go-live.
La remediation deve chiudere il rischio, non solo nasconderlo. Se una connection string è uscita, occorre ruotare la credenziale e controllare gli access log. Se un database era raggiungibile da internet, è necessario restringere la rete e verificare chi si è connesso. Se un backup era pubblico, bisogna rimuovere l’accesso, ruotare eventuali chiavi incluse e valutare cosa conteneva. Se una policy era aperta, è necessario aggiungere test negativi con utenti e tenant diversi.
Altri miglioramenti possono essere pianificati con owner e scadenza: rafforzare il naming delle variabili, automatizzare il secret scanning, documentare gli utenti DB, ridurre la retention, migliorare gli alert, separare meglio staging e produzione. La protezione del database e delle sue copie deve però essere trattata come requisito di pubblicazione, non come rifinitura successiva.
Come ISGroup può verificare database, storage e API
ISGroup può verificare se un’app creata con AI espone il database attraverso configurazioni, credenziali, superfici online, API, backup, storage o cloud. Il controllo parte dal modo reale in cui il dato viene raggiunto: rete, app, BaaS, storage, pipeline e agenti.
| Se il progetto ha… | Rischio principale | Controllo consigliato |
|---|---|---|
| Database, host, servizi, pannelli o endpoint raggiungibili | Esposizioni tecniche e configurazioni note | Vulnerability Assessment |
| Web app, API, export, upload o route che leggono dati | Abuso applicativo e accesso non autorizzato | Web Application Penetration Testing |
| Cloud database, bucket, IAM, security group, VPC, BaaS o backup | Misconfiguration cloud o privilegi eccessivi | Cloud Security Assessment |
| Connection string, query, policy, utenti DB o logica server-side nel codice | Errori di implementazione e segreti nel codice | Code Review |
| AI coding usato in modo continuativo su database, migration e deploy | Controlli non ripetibili sulle release | Software Assurance Lifecycle |
La scelta del controllo dipende da dove può uscire il dato: database raggiungibile, API abusabile, backup esposto, bucket pubblico, chiave nel codice o agente con permessi eccessivi. Prima della beta conviene delimitare questi percorsi e chiudere le esposizioni più critiche.
Hai creato un’app con AI e stai per collegarla a dati reali? ISGroup può verificare database, storage, API, credenziali, backup, regole e configurazioni prima che l’MVP diventi un rischio operativo.
Evidenze da preparare
Per avviare una verifica è utile preparare un elenco dei database, provider, ambienti, connection string gestite, utenti DB, ruoli, policy, backup, storage, API, repository, pipeline, agenti usati e parti generate con AI. Se si usa un BaaS, è necessario includere il progetto Supabase o Firebase con regole, bucket e chiavi; se si usa un cloud database, includere rete, security group, IP allowlist, VPC e account di servizio.
Servono anche dati di test: due utenti, due tenant se presenti, record simili, file caricati, export, backup e account a privilegi diversi. Senza questi elementi, è difficile dimostrare se l’app isola davvero dati e copie. Se si sono già ricevuti alert su secret, regole permissive, database pubblici, bucket aperti o dump condivisi, è opportuno includerli: spesso un alert singolo rivela un processo che va corretto prima del go-live.
Decisione prima del go-live
Blocca il go-live se trovi connection string di produzione esposte, database raggiungibile da reti non previste, RLS o Security Rules aperte su dati privati, utenti database troppo privilegiati, backup o dump scaricabili, bucket pubblici con documenti privati, API che esportano dati senza autorizzazione o agenti con credenziali di produzione non controllate.
Puoi pianificare dopo il rilascio solo miglioramenti con rischio residuo chiaro: documentazione, alert aggiuntivi, riduzione progressiva di privilegi non critici, naming delle chiavi, automazione di controlli. La protezione del dato operativo deve essere chiusa prima di usare clienti, pagamenti, documenti o informazioni aziendali.
Checklist database esposto
- Cerca connection string e credenziali in codice, file .env, history, prompt, log e artifact.
- Verifica IP allowlist, firewall, security group, VPC e accesso amministrativo.
- Controlla RLS, Security Rules, ACL e policy su tabelle e storage.
- Usa utenti DB a privilegi minimi, separati per ambiente.
- Proteggi backup, dump, snapshot, export e report.
- Testa API, route di debug, export e dashboard che leggono dal database.
- Verifica bucket, URL firmati, anteprime e metadati collegati ai record.
- Evita dati reali in staging, preview e ambienti agentici.
- Isola vector database e retrieval per utente o tenant.
- Limita agenti AI e tool MCP con accesso al database.
Domande frequenti
- Database esposto significa per forza accesso pubblico diretto?
- No. Può significare anche connection string esposta, backup scaricabile, API troppo permissiva, bucket pubblico, RLS disabilitata, staging con dati reali o vector database senza isolamento.
- Se il database non è pubblico, sono al sicuro?
- Non necessariamente. Il dato può uscire tramite API, export, log, backup, storage, credenziali nel codice o agenti con accesso al database.
- Che differenza c’è tra Vulnerability Assessment e Web Application Penetration Testing in questo caso?
- Il Vulnerability Assessment aiuta a mappare servizi e configurazioni esposte. Il WAPT prova se app e API permettono di leggere o modificare dati in modo abusivo.
- Supabase o Firebase evitano il problema?
- Offrono controlli utili, ma RLS, Security Rules, bucket, chiavi, utenti e separazione degli ambienti devono essere configurati e testati sul progetto reale.
- I backup vanno protetti come il database?
- Sì. Spesso contengono più dati del database operativo e sono meno monitorati. Dump, snapshot ed export con dati reali devono avere accessi, retention e storage controllati.
- Cosa cambia con un vector database?
- Il dato può essere recuperato come contesto del modello. Se filtri, namespace o tenant isolation non funzionano, un utente può ricevere informazioni indicizzate da documenti altrui.
Le vulnerabilità delle applicazioni web possono esporre la tua azienda a rischi e attacchi informatici.
Affidati a ISGroup per:
- Web Application Penetration Test efficace e mirato
- Individuazione e correzione preventiva delle falle di sicurezza
- Supporto tecnico da esperti in sicurezza applicativa
Fonti e riferimenti utili
- Supabase Row Level Security: https://supabase.com/docs/guides/database/postgres/row-level-security
- Supabase Hardening Data API: https://supabase.com/docs/guides/database/hardening-data-api
- Supabase Securing your API: https://supabase.com/docs/guides/api/securing-your-api
- Firebase Security Rules: https://firebase.google.com/docs/rules/
- Firebase Realtime Database Security Rules: https://firebase.google.com/docs/database/security
- MongoDB Atlas IP Access List: https://www.mongodb.com/docs/atlas/security/ip-access-list/
- PostgreSQL Connections and Authentication: https://www.postgresql.org/docs/current/runtime-config-connection.html
- Pinecone multitenancy: https://docs.pinecone.io/guides/get-started/implement-multitenancy
- OWASP API Security: https://owasp.org/www-project-api-security/
- OWASP Top 10 for LLM Applications: https://genai.owasp.org/llm-top-10/

