Se hai creato un'app con Claude o Cursor e stai per consegnarla a un client pagante, fermati. Il codice generato dall'IA arriva con buchi di sicurezza prevedibili — API key esposte, validazione dell'input mancante, permessi del database predefiniti che permettono a qualsiasi utente di vedere i dati di tutti gli altri. Questi non sono casi limite. Accadono in quasi ogni primo passaggio di una codebase generata dall'IA.
Questa guida è la checklist di sicurezza pre-lancio. Seguila passo dopo passo prima che un vero utente 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.
Perché il Codice Generato dall'IA Ha Problemi di Sicurezza
I modelli di IA si ottimizzano per "funziona?" non per "è sicuro?" Quando dici a Claude "costruiscimi un gestore di attività 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, convalidare che i campi di input non possano accettare script dannosi, nascondere le tue API key dagli strumenti per sviluppatori del browser, o aggiungere rate limiting per impedire a qualcuno di colpire i tuoi endpoint.
Questi non sono fallimenti dell'IA — sono lacune nel prompt. L'IA costruisce quello che hai chiesto. Probabilmente non hai chiesto sicurezza perché eri concentrato sulle funzionalità. Ora è il momento di tornare indietro e aggiungerla.
Passo 1: Controlla le Tue Variabili d'Ambiente
Questo è l'errore più comune e più pericoloso nelle app vibe-coded. Controlla ogni file nel tuo progetto alla ricerca di API key hardcoded, URL del database, o segreti.
Cosa cercare: Cerca nella tua 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 nelle variabili d'ambiente. In Next.js, solo le variabili prefissate con NEXT_PUBLIC_ sono esposte al browser. L'URL del tuo database, la chiave del ruolo di servizio, e i segreti dell'API non dovrebbero mai avere questo prefisso.
# .env.local (NON fare mai 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 commit dei segreti su Git, sono nella tua cronologia anche dopo l'eliminazione — ruota (rigenera) ogni chiave esposta immediatamente.
Passo 2: Abilita Row-Level Security in Supabase
Questo è il singolo passo più critico se stai usando Supabase. Per impostazione predefinita, le tabelle di 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 Row-Level Security (RLS) su ogni tabella, poi crea policy che limitano l'accesso.
Vai al tuo dashboard Supabase → Table Editor → seleziona ogni tabella → fai clic su "RLS Disabled" per abilitarlo. Poi aggiungi le policy:
Per un'app tipica dove gli utenti dovrebbero vedere solo i propri dati, crea una policy SELECT: auth.uid() = user_id. Crea policy simili per INSERT, UPDATE, e DELETE.
Testalo: Accedi come Utente A, prova ad 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'IA: Claude spesso genera query di Supabase usando la chiave service_role (che bypassa RLS) invece della chiave anon con proper policy RLS. Controlla che il tuo codice lato client usi solo la chiave anon. La chiave service role dovrebbe esistere solo nel codice lato server (API routes, server actions) e mai essere esposta al browser.
Passo 3: Aggiungi Autenticazione Correttamente
Il codice di autenticazione generato dall'IA 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 generalmente vanno bene, ma verifica). Assicurati che il logout invalidi effettivamente la sessione, non solo cancelli il cookie locale.
Requisiti delle password: Se hai autenticazione email/password, applica una lunghezza minima della password (8+ caratteri). Supabase gestisce questo nelle tue impostazioni di 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 controlla una sessione valida e reindirizza gli utenti non autenticati alla pagina di login. Non fare affidamento solo su controlli lato client — un utente può bypassarli colpendo la tua API direttamente.
Verifica email: Abilita la conferma email nelle impostazioni di Supabase Auth. Questo previene alle persone di creare account con indirizzi email falsi e aggiunge un livello base di validità dell'account.
Trovi valore in questo? Pubblichiamo un approfondimento alla settimana su AI tools, workflows, e guide pratiche. Unisciti ai lettori che lo scoprono per primi →
Passo 4: Valida Tutti gli Input
I moduli generati dall'IA di solito hanno una validazione di base (campi obbligatori, formato email) ma raramente proteggono da input dannosi.
Cosa aggiungere:
Validazione lato server su ogni endpoint API. Non fidarti mai della validazione lato client da sola — può essere bypassata 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.
Sanifica HTML in qualsiasi contenuto generato dall'utente che viene visualizzato. Se la tua app ha commenti, descrizioni, o qualsiasi campo di testo che si renderizza nel browser, usa una libreria come DOMPurify per eliminare script pericolosi. 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 upload generati dall'IA spesso non hanno limiti, il che significa che qualcuno potrebbe caricare un file da 2GB o un eseguibile. Aggiungi limiti di dimensione (5MB è ragionevole per la maggior parte delle app) e limita i tipi di file a quello di cui hai effettivamente bisogno (immagini, PDF, ecc.).
Passo 5: Assicura i Tuoi API Routes
Controlla ogni API route o server action nella tua app per questi problemi:
Autenticazione su ogni endpoint. Ogni API route che restituisce o modifica i dati dell'utente dovrebbe prima verificare la sessione dell'utente. L'IA spesso genera API route che accettano richieste da chiunque.
Autorizzazione oltre l'autenticazione. Anche dopo aver confermato che un utente è loggato, verifica che sia autorizzato ad accedere alla risorsa specifica che sta richiedendo. "L'Utente A è loggato" 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, o per raschiare dati o per sovraccaricare il tuo server. Aggiungi il basic rate limiting usando una libreria come rate-limiter-flexible o usa il rate limiting integrato di Vercel sulle Edge Functions.
Metodi HTTP. Assicurati che i tuoi API route rispondano solo ai metodi HTTP che dovrebbero. Una route che gestisce le richieste POST non dovrebbe anche rispondere alle richieste DELETE a meno che tu non l'abbia esplicitamente progettato.
Passo 6: Controlla la Tua Configurazione di Deployment
La tua piattaforma di deployment ha impostazioni di sicurezza che l'IA non configura per te.
Impostazioni di Vercel da controllare: Abilita "Deployment Protection" (richiede auth per visualizzare i deployment preview — impedisce ai client di condividere accidentalmente gli URL di anteprima che espongono il lavoro in corso). Imposta i 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 client, imposta il loro dominio personalizzato con HTTPS. Vercel e Netlify gestiscono automaticamente SSL. 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 (impedisce al tuo sito di essere incorporato in iframe per clickjacking), Strict-Transport-Security (forza HTTPS). Questi sono aggiunte una tantum che prevenire intere classi di attacchi.
Passo 7: Esegui una Scansione di Sicurezza Finale
Prima di consegnare qualcosa a un client, esegui questi controlli gratuiti:
npm audit: Esegui npm audit nella tua directory di progetto. Contrassegna le vulnerabilità note nelle tue dipendenze. Correggi i problemi critici e di alta severità. Esegui npm audit fix per correzioni automatiche dove disponibili.
Lighthouse: Apri il tuo sito distribuito in Chrome, apri DevTools, esegui un audit di Lighthouse. Controlla il punteggio "Best Practices" — rileva i problemi di sicurezza comuni come HTTPS mancante, librerie vulnerabili, e header non sicuri.
Test manuale: Accedi come Utente, prova ad accedere ai dati di un altro utente modificando URL o chiamate API. Prova a inviare form vuoti, input oversized, e caratteri speciali (come payload XSS codificati). Se qualsiasi di questi funziona, hai problemi da correggere.
La Checklist Pre-Lancio
Stampa questa e controlla ogni elemento prima di andare live:
- Tutti i segreti nelle variabili d'ambiente (nessuna chiave hardcoded)
.env.localin.gitignore(e nessun segreto nella cronologia di Git)- Supabase RLS 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 API route
- Controlli di autorizzazione (verifica di proprietà) su 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 sui endpoint API
- Header di sicurezza configurati
npm auditeseguito e problemi critici corretti- Dominio personalizzato con SSL configurato
- Deployment preview protetti
- Test di accesso ai dati tra utenti diversi passato
La Conclusione
Proteggere un'app vibe-coded non significa diventare un esperto di sicurezza. È questione di passare attraverso una checklist che cattura le lacune prevedibili che l'IA lascia dietro. I passaggi di cui sopra richiedono 2–4 ore e prevenire le vulnerabilità più comuni. Per un'app rivolte 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 ottimizzatore di prompt gratuito. E per una breakdown dei migliori coding tools, vedi Claude Code vs Codex.
Questo è quello che facciamo ogni settimana. Un approfondimento su AI tools, workflows, e opinioni oneste — senza hype, senza filler. Unisciti a noi →
Disclosure: Alcuni link in questo articolo sono affiliate link. Consigliamo solo strumenti che abbiamo testato personalmente e usiamo regolarmente. Vedi la nostra informativa completa sulla divulgazione.