Lanciare in fretta va benissimo, ma c'è una lista corta di cose che vale la pena controllare prima di aprire la tua app al mondo. Nessuna richiede di essere esperti di sicurezza, e tutte si verificano dall'esterno in un paio di minuti. Questa guida passa in rassegna ogni punto con tre cose: perché conta, come verificarlo da solo e come correggerlo, con esempi di configurazione per gli stack che le app create con l'IA usano di più (Next.js su Vercel, Supabase, Firebase). Alla fine trovi la versione da due minuti da incollare nella tua lista di lancio.
Come gli attaccanti trovano tutto questo in pochi minuti
La maggior parte delle violazioni nelle app create con l'IA non sono hack ingegnosi. Qualcuno apre il tuo sito, preme F12, legge il JavaScript che la tua app ha già inviato al suo browser e copia un URL che la tua app già chiama. Gli scanner automatici fanno lo stesso su larga scala, colpendo percorsi comuni come /.env o /.git su migliaia di siti al giorno senza nemmeno sapere che esisti. Tutto ciò che segue è qualcosa che possono verificare senza alcun accesso al tuo codice, ed è esattamente per questo che dovresti verificarlo per primo.
1. Nessun segreto nel frontend
Perché conta. Le chiavi API e i token stanno solo sul server. Quando un assistente IA "collega" un servizio, spesso butta la chiave direttamente nel codice client, dove chiunque può leggerla nei DevTools. Una chiave Stripe sk_live_ trapelata può muovere soldi veri; una chiave Supabase service_role consegna tutto il tuo database; una chiave OpenAI o Anthropic ti lascia a pagare la bolletta di qualcun altro.
Come verificare. Apri il tuo sito, premi F12 → scheda Sources (o Network filtrato per JS) e cerca nei file stringhe come sk_live, service_role, AKIA, sk-ant, AIza o -----BEGIN. Se il tuo framework usa variabili con prefisso pubblico (NEXT_PUBLIC_, VITE_, NUXT_PUBLIC_), assicurati che nessuna contenga un segreto: quel prefisso significa letteralmente "questo va nel browser".
Come correggere. Sposta ogni segreto in una variabile d'ambiente del server e fai la chiamata da una route API o da una funzione serverless; il browser parla con il tuo server, mai con il fornitore. E ruota la chiave trapelata: una volta finita in un bundle pubblico, trattala come compromessa anche dopo averla rimossa. Di più in i segreti che la tua app fa trapelare nel browser.
2. HTTPS e header di sicurezza
Perché conta. Servi tutto via HTTPS e reindirizza l'HTTP verso di esso, così nessuno può leggere o manomettere il traffico. Poi aggiungi gli header che i browser usano per difendere i tuoi utenti: Content-Security-Policy per contenere le iniezioni, Strict-Transport-Security per bloccare l'HTTPS, X-Frame-Options contro il clickjacking e X-Content-Type-Options per impedire al browser di "indovinare" i tipi di file. La maggior parte delle app generate esce senza nessuno di questi per default.
Come verificare. Richiedi il tuo sito con curl -I https://tuodominio.com e guarda gli header che tornano, oppure usa il verificatore gratuito di header di sicurezza.
Come correggere. In Next.js li dichiari in next.config.js; su Vercel, per qualsiasi framework, in vercel.json:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
La CSP merita un momento a parte: inizia in modalità Content-Security-Policy-Report-Only, guarda cosa bloccherebbe e passala in modalità attiva quando non rompe più nulla. Vedi gli header di sicurezza HTTP spiegati.
3. Regole del database (RLS) su ogni tabella
Perché conta. Se usi Supabase o Firebase, la tua app parla con il database direttamente dal browser, quindi le regole del database sono l'unica cosa tra un visitatore e i tuoi dati. Senza, chiunque abbia la chiave pubblica legge e scrive nelle tue tabelle senza fare login: esattamente la falla dietro la vulnerabilità RLS di Lovable.
Come verificare. Con l'app aperta, copia una chiamata /rest/v1/ dalla scheda Network e aprila in una finestra in incognito. Se restituisce dati senza sessione, sei esposto. In Supabase, il Table Editor segnala le tabelle con un badge rosso "RLS disabled". In Firebase, verifica che le regole non siano ancora in modalità test (allow read, write: if true o con una data di scadenza).
Come correggere. Attiva il Row-Level Security su ogni tabella con una policy di negazione per default e scrivi regole per operazione legate all'utente. In Supabase, il minimo per una tabella con una colonna user_id:
alter table public.items enable row level security;
create policy "items: solo le proprie righe" on public.items
for all to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
E non affidarti mai a un pulsante nascosto nell'interfaccia: la richiesta esiste comunque.
4. Nessun file sensibile esposto
Perché conta. Una sola richiesta a /.env può consegnare ogni segreto che la tua app usa; /.git/config permette a chiunque di scaricare tutto il tuo repository; le source map pubblicate permettono di ricostruire il tuo codice originale; un backup.sql dimenticato è il tuo database in un file.
Come verificare. Prova tuodominio.com/.env, /.git/HEAD, /.DS_Store, /backup.sql nel browser, e apri un file JS del tuo bundle per vedere se termina con una riga //# sourceMappingURL= che punta a un .map raggiungibile. Su piattaforme come Vercel o Netlify il .env non viene mai pubblicato, ma su un VPS con nginx o Apache succede.
Come correggere. Blocca i dotfile sul server (in nginx, location ~ /\. { deny all; }), disattiva le source map in produzione (productionBrowserSourceMaps: false in Next.js, build.sourcemap: false in Vite) e sposta i backup fuori dalla cartella pubblica.
5. CORS blindato
Perché conta. Una policy CORS che riflette qualsiasi origine con credenziali permette a un sito malevolo di leggere i dati dei tuoi utenti usando la loro sessione. Access-Control-Allow-Origin: * senza credenziali è innocuo per dati pubblici; il pericolo è rimandare indietro qualunque origine chieda e aggiungere Access-Control-Allow-Credentials: true.
Come verificare. Richiedi uno dei tuoi endpoint API con curl -I -H "Origin: https://evil.example" https://tuodominio.com/api/qualcosa. Se la risposta restituisce quella stessa origine in Access-Control-Allow-Origin più Allow-Credentials: true, hai il problema.
Come correggere. Tieni una lista chiusa di origini consentite (i tuoi domini di produzione e, al massimo, quello di preview) e confronta con quella; qualsiasi altra origine non riceve nessun header.
6. Cookie e sessioni configurati bene
Perché conta. I cookie di sessione devono avere Secure (solo HTTPS), HttpOnly (illeggibili da JavaScript, così un XSS non può rubarli) e SameSite=Lax o Strict (difende dal CSRF). Sono una riga di configurazione e chiudono un'intera classe di bug di furto di account.
Come verificare. F12 → Application → Cookies e guarda le colonne Secure, HttpOnly e SameSite del tuo cookie di sessione. Se usi un provider di auth (Supabase Auth, Clerk, NextAuth) di solito escono corretti; quelli che falliscono sono i cookie che la tua app aggiunge da sé.
Come correggere. Quando imposti il cookie: Set-Cookie: session=…; Secure; HttpOnly; SameSite=Lax; Path=/. In Express, res.cookie(name, value, { secure: true, httpOnly: true, sameSite: 'lax' }).
7. Dipendenze con vulnerabilità note
Perché conta. La tua app si porta dietro centinaia di pacchetti. Una versione vulnerabile di una libreria che analizza input dell'utente è un punto d'ingresso che non hai scritto tu ma che è comunque tuo.
Come verificare e correggere. Esegui npm audit nel progetto e risolvi prima i risultati critici e alti; attiva Dependabot o Renovate sul repository così le patch arrivano da te. Se il tuo sito espone un package.json pubblico, stai anche annunciando le tue versioni.
8. Limiti di frequenza sugli endpoint che costano soldi o aprono porte
Perché conta. Il form di login, la registrazione, l'invio di email e qualsiasi endpoint che chiama un'API IA a pagamento hanno bisogno di un limite per IP o per account. Senza, uno script prova migliaia di password o fa lievitare una bolletta di token in una notte.
Come correggere. Un rate limit semplice lato server (per IP e per minuto) e, presso i fornitori a pagamento, un tetto di spesa configurato nella loro dashboard. I provider di auth di solito hanno già i limiti ai tentativi attivi: verifica di non averli disattivati.
9. Errori che non dicono troppo
Perché conta. Una pagina di errore con lo stack trace completo, la query SQL o il percorso del server è una mappa per chi attacca. Lo stesso vale per header come X-Powered-By che annunciano versioni esatte.
Come correggere. Pagine di errore generiche in produzione, con il dettaglio solo nei tuoi log. Rimuovi X-Powered-By (in Next.js, poweredByHeader: false).
10. Dominio ed email pronti per utenti veri
Perché conta. Se invii email (conferme, reset della password), senza SPF, DKIM e DMARC finiranno nello spam o, peggio, chiunque potrà inviare mail spacciandosi per il tuo dominio. E un certificato o un dominio in scadenza butta giù tutto il sito.
Come verificare e correggere. Pubblica i record SPF e DMARC nel DNS, attiva il DKIM presso il tuo fornitore di invio e attiva il rinnovo automatico del dominio e del certificato. Mezz'ora di lavoro che evita il peggior giorno possibile.
In che ordine correggere se hai un'ora
- Prima, i segreti nel frontend e le regole del database: le due falle che consegnano dati veri a chiunque.
- Poi, i file esposti e il CORS: economici da correggere e molto sondati dagli scanner automatici.
- Dopo, header, cookie e pagine di errore: rafforzano ciò che già funziona.
- Infine, dipendenze, limiti di frequenza ed email: meno urgenti il giorno del lancio, essenziali la settimana dopo.
La tua checklist da 2 minuti prima del lancio
- Nessun
sk_live_,service_roleo chiave privata nel tuo JavaScript; variabili pubbliche controllate. - HTTPS forzato, con HSTS, X-Frame-Options, X-Content-Type-Options e una CSP almeno in modalità report.
- Row-Level Security (o regole Firebase) su ogni tabella; il test in incognito restituisce vuoto.
.env,.git, backup e source map non raggiungibili.- CORS limitato alle tue origini, senza mai rimandare indietro l'origine con credenziali.
- Cookie con Secure, HttpOnly e SameSite.
npm auditpulito da risultati critici e alti.- Limiti ai tentativi su login, registrazione ed endpoint IA; tetti di spesa presso i fornitori.
- Pagine di errore senza trace; nessun
X-Powered-By. - SPF, DKIM e DMARC pubblicati; rinnovo automatico di dominio e certificato.
Togliti il pensiero
Invece di controllare tutto a mano, lancia Scanaris: verifica questi punti e una quarantina di altri sul tuo sito online in 30 secondi, ordina i risultati per impatto e ti dà un prompt pronto da incollare per correggere ciascuno con la tua IA, prima che li trovi qualcun altro. Attiva il monitoraggio e ti avvisa quando qualcosa di questa lista si rompe di nuovo dopo il lancio.
Domande frequenti
Sostituisce un audit di sicurezza professionale?
No. Questa lista copre ciò che si può verificare dall'esterno e ciò che fallisce in quasi tutte le app create con l'IA. Un audit esamina anche la tua logica di business, i permessi tra utenti e il codice stesso. Ma senza questa lista, l'audit partirebbe dagli stessi punti.
Quanto tempo richiede tutto questo?
Verificare: dieci minuti con uno scanner o mezz'ora a mano. Correggere: tra un pomeriggio e un giorno a seconda di quanti punti falliscono; segreti e RLS richiedono più tempo perché ti costringono a spostare codice sul server.
E dopo il lancio?
Ripeti la lista ogni volta che l'IA genera una nuova funzionalità che tocca dati o chiavi, e imposta una nuova scansione automatica settimanale: le app si rompono per i cambiamenti, non per il tempo.