CVE-2025-48757 è una vulnerabilità di Lovable classificata come critica (CVSS 9.3) che ha esposto più di 170 applicazioni. Il problema: chiunque, senza fare login, poteva leggere —e in molti casi modificare— i dati del tuo database: nomi, email, chiavi API di terze parti, persino lo stato dei pagamenti. La causa di fondo non è un bug nascosto di Lovable, ma un pattern comune a quasi tutte le app "vibe-coded": affidare tutta la sicurezza del database alle policy RLS di Supabase… e lasciarle incomplete.
Cos'è successo davvero
Lovable crea app in cui il browser parla direttamente con il database (Supabase) tramite chiamate REST, usando la chiave pubblica anon. È un design valido a patto che ogni tabella abbia policy di Row-Level Security (RLS) che decidano quali righe ogni utente può leggere o toccare. La vulnerabilità è emersa perché molti progetti sono stati pubblicati con tabelle che avevano RLS assente o insufficiente. A un attaccante bastava modificare la richiesta REST —cambiare un filtro nell'URL— per chiedere "tutte le righe" di una tabella che avrebbe dovuto essere protetta.
È stata segnalata a marzo 2025 da Matt Palmer e Kody Low, e in modo indipendente da Danial Asaria, con divulgazione pubblica il 29 maggio 2025 (analisi tecnica, scheda CVE). Qualsiasi progetto Lovable che usi un database creato entro il 15 aprile 2025 potrebbe essere coinvolto.
Perché ti riguarda anche se non usi Lovable
Questo non è un problema esclusivo di Lovable. Qualsiasi app che parla con Supabase direttamente dal browser —che tu l'abbia costruita con Bolt, v0, Cursor o a mano— si affida al fatto che l'RLS sia corretto su ogni tabella. L'app sembra perfetta, il login funziona, ma la vera sicurezza vive nel database, non nell'interfaccia. Nascondere un pulsante nel frontend non protegge nulla: la richiesta REST resta lì per chiunque sappia dove guardare.
Come sapere se la tua app è vulnerabile
- Apri i DevTools (F12) → scheda Network mentre usi la tua app e osserva le chiamate a
*.supabase.co/rest/v1/. Copia uno di quegli URL, aprilo in una finestra in incognito (senza sessione) e verifica se restituisce dati. - Prova a chiedere troppo: se una chiamata restituisce i tuoi dati, rimuovi il filtro dall'URL. Se ti restituisce le righe di altri utenti, il tuo RLS non è efficace.
- Controlla la dashboard di Supabase → Authentication → Policies. Qualsiasi tabella con dati reali che mostra "RLS disabled" o nessuna policy è una porta aperta.
Come risolverlo
- Abilita l'RLS su ogni tabella, non solo su quelle "importanti". La regola è deny by default: senza una policy che lo consenta, non entra nessuno.
- Scrivi policy esplicite per ogni operazione (select/insert/update/delete) legate a
auth.uid(), così ogni utente tocca solo le proprie righe. - Non usare mai la chiave
service_rolenel frontend: aggira completamente l'RLS. Quella chiave vive solo sul server. - Ripeti il test con il passaggio in incognito descritto sopra: se ora la richiesta senza sessione restituisce vuoto o un errore, sei sulla strada giusta.
Come lo verifica Scanaris
Scanaris analizza il tuo sito in sola lettura e individua l'impronta di questo pattern: endpoint Supabase raggiungibili dal browser, CORS permissivo, chiavi e token esposti nel tuo JavaScript e dati che l'app serve senza sessione. Incolla il tuo URL e ti dice, in pochi secondi e ordinati per gravità, cosa è in bella vista —prima che lo trovi qualcun altro.