Se hai scritto un'app con Claude o Cursor e stai per consegnarla a un cliente pagante, fermati. Il codice generato da AI presenta vulnerabilità di sicurezza prevedibili — chiavi API esposte, validazione degli input mancante, permessi del database predefiniti che permettono a qualsiasi utente di vedere i dati di tutti gli altri. Non sono casi limite. Accadono in quasi tutti i codebase generati da AI al primo tentativo.

Questa guida è la checklist di sicurezza pre-lancio. Seguila passo dopo passo prima che qualsiasi utente reale tocchi la tua app. È scritta per lo stack di vibe coding più comune (Next.js + Supabase + Vercel), ma i principi si applicano indipendentemente dai tuoi strumenti.

Fatti Veloci
Tempo per completare
2–4 ore per un'app tipica
Competenze richieste
Nessun background di sicurezza — checklist passo dopo passo
Stack assunto
Next.js + Supabase + Vercel (adattabile)
Cosa risolverai
Autenticazione, isolamento dei dati, chiavi API, validazione, rate limit, variabili env
Quando farlo
Prima che qualsiasi utente reale o cliente acceda all'app
Ultimo controllo
Aprile 2026

Perché il codice generato da AI ha problemi di sicurezza

I modelli di AI ottimizzano per "funziona?" non "è sicuro?". Quando dici a Claude "costruiscimi un task manager con account utente", genererà codice che crea utenti, archivia attività e le visualizza. Quello che probabilmente non farà automaticamente: assicurarsi che l'Utente A non possa vedere le attività dell'Utente B, validare che i campi di input non possano accettare script dannosi, nascondere le tue chiavi API dai tool di sviluppo del browser, o aggiungere rate limiting per prevenire che qualcuno martelli i tuoi endpoint.

Questi non sono fallimenti dell'AI — sono lacune nel prompt. L'AI costruisce quello che hai chiesto. Probabilmente non hai chiesto la sicurezza perché eri focalizzato sulle funzionalità. Ora è il momento di tornare indietro e aggiungerla.

Passaggio 1: Verifica le tue variabili di ambiente

Questo è l'errore più comune e più pericoloso nelle app vibe-coded. Controlla ogni file del tuo progetto per chiavi API hardcoded, URL del database o segreti.

Cosa cercare: Cerca nel tuo codebase stringhe che iniziano con sk-, eyJ, sbp_, supabase, postgres://, o qualsiasi stringa lunga che sembra casuale. Controlla questi file specificamente: qualsiasi file nella tua directory /app o /pages, qualsiasi file di componente, il tuo next.config.js, e qualsiasi file di utilità.

La soluzione: Sposta ogni segreto in variabili di ambiente. In Next.js, solo le variabili con prefisso NEXT_PUBLIC_ sono esposte al browser. L'URL del tuo database, la chiave service role e i segreti API non dovrebbero mai avere questo prefisso.

.env.local
# .env.local (NON fare mai il commit di questo file)
SUPABASE_SERVICE_ROLE_KEY=your-secret-key
DATABASE_URL=postgres://...

# Questi vanno bene per esporre al browser:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

Verifica: Controlla che il tuo file .gitignore includa .env.local. Se hai già fatto il commit di segreti in Git, sono nella tua cronologia anche dopo l'eliminazione — ruota (rigenera) immediatamente ogni chiave esposta.

Passaggio 2: Abilita la sicurezza a livello di riga in Supabase

Questo è il passaggio più critico se usi Supabase. Per impostazione predefinita, le tabelle Supabase non hanno restrizioni di accesso — chiunque abbia la tua chiave anon può leggere e scrivere ogni riga in ogni tabella. Questo significa che l'Utente A può vedere i dati dell'Utente B con una semplice chiamata API.

La soluzione: Abilita la sicurezza a livello di riga (RLS) su ogni tabella, poi crea policy che limitano l'accesso.

Vai al tuo dashboard Supabase → Table Editor → seleziona ogni tabella → clicca "RLS Disabled" per abilitarlo. Poi aggiungi policy:

Per un'app tipica dove gli utenti dovrebbero vedere solo i loro dati, crea una policy SELECT: auth.uid() = user_id. Crea policy simili per INSERT, UPDATE, e DELETE.

Testalo: Accedi come Utente A, prova a accedere ai dati dell'Utente B tramite API. Se riesci a vederli, le tue policy sono sbagliate. Supabase ha un editor SQL dove puoi testare le policy direttamente.

Errore comune dell'AI: Claude spesso genera query Supabase usando la chiave service_role (che aggira RLS) invece della chiave anon con policy RLS appropriate. Controlla che il tuo codice lato client usi solo la chiave anon. La chiave service role dovrebbe esistere solo nel codice lato server (route API, server actions) e non essere mai esposta al browser.

Passaggio 3: Aggiungi correttamente l'autenticazione

Il codice di autenticazione generato da AI spesso funziona ma prende scorciatoie. Controlla questi problemi specifici:

Gestione delle sessioni: Assicurati che le sessioni scadano. Controlla che la tua configurazione di autenticazione includa un timeout di sessione ragionevole (i valori predefiniti di Supabase sono generalmente ok, ma verifica). Assicurati che il logout invalidhi effettivamente la sessione, non solo cancelli il cookie locale.

Requisiti password: Se hai autenticazione email/password, applica una lunghezza minima della password (8+ caratteri). Supabase gestisce questo nelle impostazioni del tuo progetto → Authentication → Password Requirements.

Route protette: Ogni pagina che mostra dati specifici dell'utente ha bisogno di middleware di autenticazione. In Next.js App Router, crea un middleware che verifica una sessione valida e reindirizza gli utenti non autenticati alla pagina di login. Non affidarti solo ai controlli lato client — un utente può raggirare quelli colpendo direttamente la tua API.

Verifica email: Abilita la conferma email nelle impostazioni di Supabase Auth. Questo previene che le persone creino account con indirizzi email falsi e aggiunge un livello base di validità dell'account.

Stai ricavando valore da questo? Pubblichiamo un approfondimento ogni settimana su strumenti AI, workflow e guide pratiche. Unisciti ai lettori che lo scoprono per primi →

Passaggio 4: Valida tutti gli input

I form generati da AI di solito hanno validazione di base (campi obbligatori, formato email) ma raramente proteggono dall'input dannoso.

Cosa aggiungere:

Validazione lato server su ogni endpoint API. Non fidarti mai della validazione lato client da sola — può essere aggirata inviando richieste direttamente alla tua API. Usa una libreria di validazione come Zod (per TypeScript) per definire schemi per ogni pezzo di dati che la tua app accetta.

Pulisci l'HTML in qualsiasi contenuto generato dall'utente che viene visualizzato. Se la tua app ha commenti, descrizioni, o qualsiasi campo di testo che renderizza nel browser, usa una libreria come DOMPurify per rimuovere script dannosi. Senza questo, qualcuno può iniettare JavaScript che ruba le sessioni di altri utenti (cross-site scripting / XSS).

Limita la dimensione e i tipi di file se la tua app accetta caricamenti di file. I gestori di caricamento generati da AI spesso non hanno limiti, significando che qualcuno potrebbe caricare un file di 2GB o un eseguibile. Aggiungi limiti di dimensione (5MB è ragionevole per la maggior parte delle app) e limita i tipi di file a quello che effettivamente ti serve (immagini, PDF, ecc.).

Passaggio 5: Assicura le tue route API

Controlla ogni route API o server action nella tua app per questi problemi:

Autenticazione su ogni endpoint. Ogni route API che restituisce o modifica dati utente dovrebbe verificare prima la sessione dell'utente. L'AI spesso genera route API che accettano richieste da chiunque.

Autorizzazione oltre l'autenticazione. Anche dopo aver confermato che un utente è registrato, verifica che sia autorizzato ad accedere alla risorsa specifica che sta richiedendo. "L'Utente A è registrato" non significa "L'Utente A può modificare il profilo dell'Utente B". Controlla la proprietà su ogni accesso ai dati.

Rate limiting. Senza rate limiting, qualcuno può inviare migliaia di richieste al secondo alla tua API, per scraping dei dati o per sovraccaricare il tuo server. Aggiungi rate limiting di base usando una libreria come rate-limiter-flexible o usa il rate limiting integrato di Vercel sulle Edge Functions.

Metodi HTTP. Assicurati che le tue route API rispondano solo ai metodi HTTP che dovrebbero. Una route che gestisce richieste POST non dovrebbe rispondere anche alle richieste DELETE a meno che non l'abbia esplicitamente progettato.

Passaggio 6: Controlla la configurazione del deployment

La tua piattaforma di deployment ha impostazioni di sicurezza che l'AI non configura per te.

Impostazioni Vercel da controllare: Abilita "Deployment Protection" (richiede autenticazione per visualizzare deployment di preview — previene che i client condividano accidentalmente URL di preview che espongono il lavoro in corso). Configura limiti di spesa per prevenire addebiti inaspettati se la tua app riceve picchi di traffico. Configura i tuoi domini consentiti negli header CORS.

Dominio personalizzato e SSL: Se stai consegnando questo a un cliente, configura il suo dominio personalizzato con HTTPS. Vercel e Netlify gestiscono SSL automaticamente. Non consegnare mai un'app client su un sottodominio .vercel.app — sembra non professionale e il client non può trasferirlo facilmente.

Header: Aggiungi header di sicurezza al tuo next.config.js o vercel.json: X-Content-Type-Options: nosniff, X-Frame-Options: DENY (previene che il tuo sito venga incorporato in iframe per clickjacking), Strict-Transport-Security (forza HTTPS). Questi sono aggiunte una tantum che prevengono intere classi di attacchi.

Passaggio 7: Esegui una scansione di sicurezza finale

Prima di consegnare qualcosa a un cliente, esegui questi controlli gratuiti:

npm audit: Esegui npm audit nella directory del tuo progetto. Segnala vulnerabilità note nelle tue dipendenze. Correggi i problemi di criticità critica e alta. Esegui npm audit fix per correzioni automatiche dove disponibili.

Lighthouse: Apri il tuo sito deployato in Chrome, apri DevTools, esegui un audit Lighthouse. Controlla il punteggio "Best Practices" — individua problemi di sicurezza comuni come HTTPS mancante, librerie vulnerabili, e header non sicuri.

Test manuale: Accedi come un utente, prova ad accedere ai dati di un altro utente modificando URL o chiamate API. Prova a inviare form vuoti, input sovradimensionati e caratteri speciali (come payload XSS codificati). Se qualcuno di questi funziona, hai problemi da risolvere.

La Checklist Pre-Lancio

Stampa questa e controlla ogni elemento prima di andare live:

  • Tutti i segreti in variabili di ambiente (nessuna chiave hardcoded)
  • .env.local in .gitignore (e nessun segreto nella cronologia Git)
  • RLS Supabase abilitato su ogni tabella
  • Policy RLS testate (L'Utente A non può vedere i dati dell'Utente B)
  • Il codice lato client usa solo la chiave anon (chiave service role solo lato server)
  • Autenticazione su ogni route API
  • Controlli di autorizzazione (verifica di proprietà) sull'accesso ai dati
  • Validazione dell'input su ogni form (lato server, non solo lato client)
  • Limiti di caricamento file (dimensione e tipo) se applicabile
  • Rate limiting su endpoint API
  • Header di sicurezza configurati
  • npm audit eseguito e problemi critici corretti
  • Dominio personalizzato con SSL configurato
  • Deployment di preview protetti
  • Test manuale di accesso ai dati tra utenti superato

Il Punto Finale

Proteggere un'app vibe-coded non è diventare un esperto di sicurezza. È eseguire una checklist che individua le lacune prevedibili che l'AI lascia dietro. I passaggi sopra richiedono 2–4 ore e prevengono le vulnerabilità più comuni. Per un'app rivolta ai client, questo non è opzionale — è la differenza tra lavoro professionale e una responsabilità.

Se stai costruendo la tua prima app vibe-coded, inizia con la nostra guida completa al vibe coding. Se vuoi migliorare i prompt che usi con Claude o Cursor, prova il nostro optimizer di prompt gratuito. E per un'analisi dei migliori tool di coding, vedi Claude Code vs Codex.

Questo è quello che facciamo ogni settimana. Un approfondimento su strumenti AI, workflow e opinioni oneste — senza hype, senza riempitivi. Unisciti a noi →

Divulgazione: Alcuni link in questo articolo sono link di affiliazione. Consigliamo solo strumenti che abbiamo testato personalmente e che usiamo regolarmente. Vedi la nostra politica di divulgazione completa.