// docs / security guides / pre-launch SaaS
Checklist sicurezza pre-lancio SaaS: 35+ voci
Mancano pochi giorni al lancio di un prodotto SaaS creato con Cursor, Claude Code, Lovable o Bolt. Questa lista di controllo è un controllo go/no-go che copre le superfici di sicurezza che gli strumenti AI mancano costantemente e che i fondatori che spediscono velocemente devono affrontare prima di prendere i soldi dei clienti. Otto sezioni, più di 35 elementi, ciascuno risolvibile in 30-90 minuti. Stampalo, cancellalo, distribuiscilo con sicurezza.
Ogni elemento riportato di seguito è essenziale. Verde significa spedito e verificato; il rosso significa avvio non risolto e bloccante. Per una panoramica più dettagliata di ciascuna categoria con frammenti di codice e modelli di errore reali, vedere How to secure an app built with AI coding tools e The vibe coding security checklist.
Isolamento dei dati dei clienti
In un SaaS multi-tenant, il primo limite di sicurezza è l'isolamento dei dati. I dati di ogni cliente devono essere irraggiungibili per ogni altro cliente, e questo deve essere applicato a livello del database, non a livello dell'applicazione.
- Abilita la sicurezza a livello di riga (RLS) su ogni tabella Supabase con
ALTER TABLE public.table_name ENABLE ROW LEVEL SECURITY; ALTER TABLE public.table_name FORCE ROW LEVEL SECURITY;. FORCE impedisce al proprietario della tabella di ignorarlo. - Per ogni policy RLS, verificare gli ambiti del predicato per l'utente o l'organizzazione autenticata. Esempio:
CREATE POLICY "users_see_own" ON public.items FOR SELECT USING (auth.uid() = user_id);. Prova con un secondo account utente per verificare che i dati rimangano isolati. - Se utilizzi Firebase / Firestore, le regole devono corrispondere al tuo modello di tenant. Non utilizzare
allow read, write: if true;o regole di test con limiti di tempo. Utilizzaallow read, write: if request.auth.uid == resource.data.owner_uid;o una corrispondenza equivalente a livello di organizzazione. - Utilizza URL firmati o token di breve durata per l'accesso ai file, mai bucket pubblici. Supabase Archiviazione: imposta
ENABLE ROW LEVEL SECURITYsulla tabellaobjectse crea policy che limitino l'accesso ai file all'utente autenticato. Testare i download come utenti diversi. - Sul tuo livello API, ogni richiesta deve includere
auth.uid()o il contesto org-id. Ogni query del database deve essere filtrata in base a tale contesto. Esempio: noSELECT * FROM items WHERE id = $1; sempreSELECT * FROM items WHERE id = $1 AND user_id = auth.uid().
Fatturazione e pagamento
L'integrazione Stripe è il luogo in cui la fiducia dei clienti incontra la sicurezza finanziaria. Una configurazione errata in questo caso significa pagamenti rubati, cicli di rimborsi o entrate mancanti.
- Utilizzare live Stripe keys in produzione. Testare con un tasto di modalità test separato durante lo staging. Non passare mai dal test al live senza una scansione finale in modalità live.
- Verifica la firma del webhook su ogni evento in entrata:
const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);. Lancia se la firma fallisce. Archivia il segreto del webhook solo in una variabile di ambiente, mai nel codice. - Implementare l'idempotenza sui gestori webhook utilizzando una tabella di database con chiave
event.id. Se lo stesso webhook arriva due volte (lo farà), la seconda esecuzione non è operativa. Scrivi la riga di idempotenza nella stessa transazione del cambiamento di stato. - Su
customer.subscription.updatedecustomer.subscription.deleted, revoca immediatamente l'accesso. Non aspettare un cron. Prova annullando un abbonamento nella dashboard Stripe e verificando che l'utente sia bloccato entro 5 secondi. - Memorizza nel tuo database solo il cliente Stripe ID e l'abbonamento ID, mai la tessera completa o la chiave API. Recupera lo stato dell'abbonamento in tempo reale da Stripe su ogni limite di autenticazione (caricamento della pagina, chiamata API, controllo cron). Non memorizzare nella cache lo stato dell'abbonamento per >1 minuto.
Autenticazione e sessioni
Auth è l'obiettivo dell'attaccante di secondo ordine in SaaS. Un account utente è un vettore per dati e metodi di pagamento.
- Utilizzare
supabase.auth.getUser()su ogni percorso protetto, maigetSession().getSession()legge un cookie non verificato;getUser()convalida il lato server JWT. In Next.js:const { data: { user } } = await supabase.auth.getUser();prima di pubblicare contenuti protetti. - Imposta
SameSite=Laxsui cookie di autenticazione (Supabase Auth lo fa per impostazione predefinita). Verificare in DevTools → Applicazione → Cookie. Se vediSameSite=None, aggiungisameSite: 'Lax'alla configurazione della sessione. - Abilita MFA sul tuo account amministratore. Per MFA rivolto agli utenti, testalo end-to-end prima del lancio: registrati, registra un dispositivo TOTP, esci, accedi di nuovo con il token TOTP, verifica che funzioni.
- I token Magic-link devono scadere entro 15 minuti. I token di reimpostazione della password devono scadere entro 1 ora. I token di sessione (JWTs) possono durare più a lungo (24 ore su 7, 7 giorni su 7) ma devono essere convalidati a ogni utilizzo. Controlla le impostazioni predefinite del tuo provider di autenticazione.
- Verifica la completezza della disconnessione: dopo che un utente fa clic su Esci, il browser elimina la sessione di autenticazione, il server revoca eventuali token e l'utente non può accedere alle pagine protette. In Supabase: chiama
await supabase.auth.signOut()e verifica che JWT non sia più valido alla richiesta successiva.
PII e conformità
Se raccogli email, nome, informazioni di pagamento o qualsiasi PII, hai obblighi legali: minimizzazione dei dati, archiviazione sicura, cancellazione su richiesta e disponibilità DPA.
- Scrivi e pubblica un'informativa sulla privacy (non facoltativa, anche per SaaS indipendente). Indica quali dati raccogli, perché, per quanto tempo li conservi e i diritti dell'utente (accesso, correzione, cancellazione). Utilizza un modello di Termly o simile ma personalizzalo.
- Implementare un endpoint delete-account API che elimini PII dal database. Provalo: crea un account, aggiungi dati, elimina l'account, verifica che i dati siano scomparsi (usa l'ispezione diretta del database).
- Per conformità GDPR / CCPA, rispondere alle richieste dell'interessato (accesso/correzione/cancellazione) entro 30 giorni. Documenta il tuo processo. Se la tua app è basata su EU- o serve EU utenti, è richiesto un addendum per l'elaborazione dei dati Pro (DPA) con Stripe, Supabase ed eventuali processori.
- Crittografa i campi sensibili quando non sono attivi (le password vengono sottoposte ad hashing dal tuo provider di autenticazione; ma la tokenizzazione della carta di credito, le chiavi API e i segreti devono utilizzare
pgcryptoo un deposito esterno). Non memorizzare mai i numeri di carta di credito in chiaro (usa invece la tokenizzazione Stripe).
Prontezza operativa
La sicurezza è continua. La risposta agli incidenti, il monitoraggio e i runbook iniziano prima del primo giorno.
- Imposta una pagina di stato (Statuspage.io, Uptime Robot o un semplice index.html). I clienti devono sapere se si sta verificando un'interruzione. Aggiornalo su ogni incidente.
- Avere una rotazione di guardia documentata e testata. Chi si sveglia con un avviso alle 2 del mattino? Chi ha le chiavi di distribuzione? Chi può revocare un token compromesso? Documentalo ed esegui un'esercitazione antincendio prima del lancio.
- Scrivi un runbook di risposta agli incidenti di sicurezza: cosa fare se un cliente segnala una violazione, se si perde una chiave, se un servizio si interrompe. Distribuiscilo alla tua squadra. Testare uno scenario (e.g., simulare una perdita di chiave) per verificare che il piano funzioni.
- Le procedure di backup e ripristino devono essere testate, non teoriche. Puoi ripristinare dai backup? Tempo. Supabase: abilita i backup automatici (conservazione di 7 giorni gratuitamente, 30 giorni a pagamento). Testare trimestralmente un ripristino su un progetto separato.
- Abilita la registrazione di controllo per operazioni privilegiate: Stripe accessi al dashboard, Supabase chiamate amministratore API, modifiche allo schema del database, riconciliazione dei pagamenti. Strumenti: CloudTrail (AWS), log di controllo Supabase, estensione PostgreSQL
pgaudit.
Superficie d'attacco esterna
Il tuo confine API è costantemente sotto controllo da parte degli aggressori. Bloccalo prima che colpisca il traffico dannoso.
- Limita la velocità di ogni endpoint pubblico. Esempio: 100 richieste al minuto per IP all'iscrizione, 10 al minuto alla reimpostazione della password. Utilizza Vercel KV, Redis o simili. Fallisci con 429 (troppe richieste).
- Aggiungi CAPTCHA (hCaptcha o reCAPTCHA) agli endpoint di registrazione e reimpostazione della password per sconfiggere i bot. Verificare il token lato server prima di accettare la richiesta.
- Utilizzare WAF (Web Application Firewall) se disponibile: Cloudflare, Vercel Web Application Firewall o AWS WAF. Blocca automaticamente IP e pattern noti come dannosi.
- Cerca endpoint API aperti. Esegui mensilmente una scansione passiva FixVibe sul tuo dominio di produzione. Esaminare i risultati per i percorsi di debug esposti, l'introspezione GraphQL, la fuga di chiavi API o l'esposizione della configurazione.
- Ruotare le credenziali (API chiavi, OAuth token, password del database) trimestralmente. Documentare la procedura di rotazione e automatizzarla ove possibile.
Osservabilità e registrazione
Quando le cose vanno male, i registri sono il tuo record forense. Configurali dal primo giorno.
- Centralizza i log: Supabase Log, Vercel Log, log dell'applicazione e log di autenticazione in un unico dashboard (Datadog, LogRocket o self-hosted ELK). Ricercabile, conservato per almeno 90 giorni.
- Avviso su eventi di sicurezza: accessi ripetuti non riusciti (possibile furto dell'account), utilizzo insolito di API (possibile scraping), picchi di errori (possibile attacco o incidente legittimo). Imposta soglie e integrazioni Slack.
- Emetti log di controllo per ogni operazione privilegiata: modifiche del ruolo utente, creazione di nuovi account amministratore, aggiunte di metodi di pagamento, modifiche dell'ambito nelle chiavi API. Archiviali separatamente dai registri dell'applicazione con conservazione immutabile.
Verifica finale
Prima di annunciare, esegui una scansione FixVibe completa ed esamina i risultati con un occhio attento alla sicurezza.
- Esegui una scansione attiva FixVibe Pro sul tuo dominio di produzione. Configura il tuo dominio per il test attivo (DNS TXT o HTTP verifica file). Autorizzare la scansione ed esaminare ogni risultato, in particolare quello critico e di gravità elevata. Correggi o accetta ciascuno di essi esplicitamente.
- Abilita nuove scansioni pianificate: Pro piano → 3 ore, 6 ore, 12 ore o quotidianamente. Piano Unlimited → 6h, 12h, giornaliero, ogni 2 giorni o settimanale. Abbina i controlli active IDOR walking, SQL injection e reflected XSS sul tuo dominio verificato.
- Configura i webhook: connetti FixVibe a Slack o invia un'e-mail in modo che i risultati critici attivino avvisi in tempo reale. Vedere /docs/webhooks per la configurazione.
- Eseguire una revisione manuale finale del codice concentrandosi sui trucchi in /docs/security-guides/ai-generated-code-security-scanner: segreti nei bundle, RLS/rules, limiti di autenticazione, CSP, posizionamento del middleware. Utilizza vibe coding security checklist come modello di recensione.
Giorno del lancio
Hai cancellato la lista di controllo. Distribuisci con fiducia. Dopo il lancio, monitora attivamente: controlla i risultati FixVibe ogni giorno per la prima settimana, rispondi agli avvisi entro 1 ora e mantieni attiva la pianificazione della scansione. Per una guida dettagliata al rafforzamento con frammenti di codice, vedere How to secure an app built with AI coding tools.
