Pronto al Lancio

Sicurezza · 6 min di lettura ·

Supabase RLS: cos'è e perché i dati della tua app sono esposti

Supabase RLS spiegata semplice: perché senza regole chiunque può leggere o modificare i dati della tua app Lovable o Bolt, e come verificarlo e sistemarlo.

Se ti stai chiedendo cos'è la RLS di Supabase o se la tua app fatta con Lovable o Bolt è davvero sicura, la risposta breve è questa. La RLS (Row Level Security, sicurezza a livello di riga) è l'insieme di regole che decide chi può leggere e modificare ogni dato del database. Se è spenta o scritta male, chiunque può leggere, modificare o cancellare i dati della tua app, anche senza fare login. Qui sotto vediamo perché succede, come verificarlo e come sistemarlo.

Perché la chiave pubblica di Supabase non ti protegge

Molte app create con l'AI usano Supabase come database. Il database è l'archivio dove finiscono utenti, ordini, messaggi. In queste app il frontend, cioè la parte che gira nel browser del visitatore, parla direttamente con il database attraverso le API di Supabase.

Per farlo usa due informazioni: l'indirizzo del progetto e la chiave pubblica (chiamata anon o publishable). Entrambe sono nel codice del sito, quindi chiunque può leggerle. Non è un errore: Supabase è progettato così.

Pensa a un condominio. L'indirizzo e il citofono sono pubblici, chiunque può suonare. La RLS è il portiere che decide chi può salire e in quale appartamento. Se il portiere non c'è, il citofono apre a tutti.

Cos'è la RLS di Supabase, in pratica

Ogni tabella è fatta di righe: un profilo, un ordine, una prenotazione. La RLS permette di scrivere delle regole, chiamate policy, che dicono per ogni operazione chi può toccare quali righe.

Una policy tipica dice: «ogni utente può vedere solo il proprio profilo». In SQL, il linguaggio dei database, si scrive così:

alter table profiles enable row level security;

create policy "Ogni utente vede solo il proprio profilo"
on profiles for select
to authenticated
using ( (select auth.uid()) = user_id );

La prima riga accende la RLS sulla tabella. La seconda crea la regola: solo gli utenti che hanno fatto login (authenticated) possono leggere (select), e solo le righe in cui la colonna user_id corrisponde al loro identificativo (auth.uid()). Se nessuno ha fatto login, auth.uid() è vuoto e la regola non lascia passare nulla.

Le policy vanno pensate per ogni operazione: lettura (select), inserimento (insert), modifica (update) e cancellazione (delete). Proteggere la lettura e lasciare aperta la cancellazione non serve a molto.

Le situazioni che espongono i dati

Queste sono le configurazioni più comuni che espongono i dati nelle app create con intelligenza artificiale.

SituazioneCosa succedeCome riconoscerla
RLS disattivata su una tabellaChiunque può leggere, modificare e cancellare tutte le righeIl Security Advisor di Supabase la segnala come errore
RLS attiva con policy using (true)Sembra protetta, ma la regola lascia passare tuttiLeggendo le policy trovi true come condizione
Solo la lettura è protettaI dati non si vedono, ma si possono modificare o cancellareMancano policy per update o delete, oppure sono troppo larghe
Regole basate sui metadati dell'utenteL'utente può modificarli da solo e darsi più permessiLe policy usano user_metadata
Viste (view) sul databaseUna vista può ignorare la RLS delle tabelle da cui leggeIl Security Advisor segnala viste con privilegi elevati
Chiave service_role o secret nel frontendLa RLS viene saltata del tuttoLa chiave compare nei file del sito
File caricati in uno spazio pubblicoDocumenti e foto sono raggiungibili da chiunque abbia il linkLo spazio di archiviazione (bucket) è impostato come pubblico

L'ultima riga merita attenzione: anche i file caricati dagli utenti, come documenti d'identità o fatture, hanno le loro regole di accesso, separate da quelle delle tabelle.

Perché succede con le app create con l'AI

Il motivo più comune è semplice. Quando la RLS è attiva e manca una regola, l'app smette di funzionare: le liste restano vuote e gli inserimenti falliscono con un errore come new row violates row-level security policy for table "orders". Chiedendo all'AI di «sistemare l'errore», la correzione più rapida è spegnere la RLS o scrivere una regola che lascia passare tutti. L'errore sparisce, la protezione pure.

Altre cause frequenti:

  • tabelle create con comandi SQL in cui la RLS non è stata accesa;
  • nuove tabelle aggiunte in un secondo momento, senza regole;
  • la chiave di servizio usata nel browser perché «con quella funziona», un errore che trattiamo nella guida sulle chiavi API esposte nel frontend;
  • un ruolo «admin» deciso da un campo che l'utente può modificare.

Se stai inseguendo messaggi come permission denied for table, trovi le spiegazioni nell'articolo sugli errori Supabase più comuni.

Come capire se i tuoi dati sono esposti

Puoi fare una prima verifica senza scrivere codice.

  1. Apri il Security Advisor di Supabase. Nella dashboard del progetto c'è una sezione dedicata ai controlli di sicurezza. Segnala, tra le altre cose, le tabelle pubbliche senza RLS, le policy che usano i metadati dell'utente e le viste che ignorano le regole.
  2. Usa lo scanner della piattaforma. Lovable, per esempio, esegue un controllo di sicurezza prima della pubblicazione e ha una vista dedicata ai problemi trovati. È utile, ma non conosce le regole della tua app: una policy che lascia passare tutti potrebbe non essere segnalata come problema.
  3. Leggi le policy, tabella per tabella. Per ognuna chiediti: chi deve poter leggere? Chi deve poter scrivere? Le regole che vedi corrispondono a quello che hai in mente?
  4. Fai una prova pratica con due account. Crea due utenti di prova. Con il primo crea dei dati, poi entra con il secondo e prova a vederli, per esempio cambiando l'identificativo nell'indirizzo della pagina. Ripeti la prova senza fare login, da una finestra in incognito.

Fai queste prove solo sulla tua app, mai su quelle di altri.

Come sistemare la RLS, passo per passo

Prima di toccare le regole, fai un backup del database: se qualcosa va storto, puoi tornare indietro. Ne parliamo nella guida sul backup del database.

  1. Fai una mappa delle tabelle. Per ognuna scrivi chi può leggere e chi può scrivere. Per esempio: «profili: ognuno legge e modifica il proprio», «prodotti: tutti leggono, solo l'admin modifica», «ordini: ognuno vede i propri, nessuno cancella».
  2. Accendi la RLS su tutte le tabelle pubbliche. Anche su quelle che sembrano innocue.
  3. Scrivi una policy per ogni operazione necessaria. Parti dal principio che tutto è chiuso e apri solo ciò che serve.
  4. Gestisci l'admin in modo sicuro. Il ruolo va salvato in una tabella che gli utenti non possono modificare, non nei metadati del profilo. Approfondiamo nella guida su ruoli e permessi admin.
  5. Controlla viste e file. Le viste devono rispettare le regole delle tabelle; gli spazi per i file privati non devono essere pubblici.
  6. Ripeti le prove con due account e senza login. Poi riapri il Security Advisor e verifica che non ci siano più errori.

Se usi un assistente AI, sii esplicito nella richiesta:

Attiva la RLS su tutte le tabelle dello schema public.
Per ogni tabella crea policy separate per select, insert,
update e delete secondo questa mappa: [incolla la tua mappa].
Non usare mai using (true) per dati degli utenti
e non disattivare la RLS per risolvere errori.

Poi rileggi le policy generate: devono corrispondere alla tua mappa, riga per riga.

Quando conviene farti aiutare

Se la tua app è ancora un prototipo con dati finti, puoi imparare molto sistemando la RLS da solo. Conviene chiedere aiuto se ci sono già utenti reali, se l'app gestisce dati personali, pagamenti o documenti, oppure se ogni regola che aggiungi rompe qualcos'altro.

Di solito facciamo una revisione completa delle tabelle, delle policy, delle viste e dei file, e proviamo l'app come la proverebbe un malintenzionato. Se vuoi capire a che punto sei, prenota una call gratuita e ne parliamo insieme.

Domande frequenti

Vuoi che ci guardiamo noi?

Prenota una call gratuita di 20 minuti: ci racconti il problema, ti diciamo cosa serve e quanto costa. Senza impegno.

Prenota la call gratuita

Potrebbe interessarti anche