← Guide per stack

Bolt

Sicurezza per la tua app Bolt

Bolt.new crea un'app full-stack nel browser e la mette online con un clic, ma quella velocità nasconde decisioni di sicurezza: chiavi che incolli nella chat e finiscono nel frontend, zero header e una SPA che l'AI non riesce a vedere. Scansiona la tua app e scoprilo con certezza in 30 secondi.

Rischi tipici con Bolt

Chiavi incollate nella chat che finiscono nel frontend

Per "collegare" un servizio incolli la chiave in Bolt, che spesso la inserisce nel codice client. Tutto ciò che arriva al browser è pubblico: quella chiave è in bella vista.

Deploy senza header di sicurezza

Il deploy di Bolt serve la tua app in HTTPS ma senza CSP, HSTS o X-Frame-Options. Questi header non ci sono di default e vanno aggiunti sull'host.

SPA invisibile a motori di ricerca e AI

Bolt genera SPA il cui contenuto appare solo dopo l'esecuzione di JavaScript. I crawler dell'AI e alcuni motori di ricerca vedono una pagina quasi vuota e non riescono a indicizzarti né a citarti.

"Sicurezza in Bolt" sono due cose che conviene tenere separate. La prima è il progetto Bolt in sé: cosa incolli nella chat, dove finiscono le variabili d'ambiente, con chi condividi il progetto e dove viene fatto il deploy. La seconda è il codice che Bolt genera, quasi sempre una SPA con Vite e React collegata a Supabase, che porta gli stessi cinque o sei difetti di sempre. Questa guida copre entrambe, con un file di istruzioni perché Bolt applichi le regole a ogni generazione, un prompt di revisione prima del deploy e il modo di verificare il risultato dall'esterno.

Parte 1: proteggere il tuo progetto Bolt

Bolt gira nel tuo browser, e questo cambia dove vivono le chiavi

Bolt esegue l'intero progetto dentro il browser con WebContainers. Non c'è un server tuo mentre sviluppi, quindi qualsiasi chiave che metti in un file .env è nel progetto, e se ha il prefisso VITE_ finisce incorporata nel bundle che viene pubblicato. Per il browser va bene solo con chiavi pubbliche (la anon di Supabase, la publishable di Stripe). Quelle segrete non hanno posto nel frontend: vanno in una Edge Function di Supabase o in una funzione di Netlify, e il client chiama la funzione.

Quello che incolli nella chat finisce nel codice

Se incolli una chiave nella conversazione per "collegare" un servizio, il modello la scrive dove gli serve, di solito in un componente. Da lì viaggia verso tutti i visitatori. La regola: le chiavi pubbliche vanno in .env; quelle segrete nel pannello del servizio che esegue la funzione (Supabase o Netlify), mai nella chat. E se ne hai incollata una per errore, ruotala: la cronologia la conserva anche se la cancelli dal codice.

Condividere, esportare e fare il deploy

Un link di progetto condiviso mostra il codice completo, .env compreso. Prima di condividere, controlla cosa c'è dentro. Se esporti su GitHub, rendi privato il repository e tieni .env nel .gitignore. Il deploy con un clic va su Netlify, su un sottodominio .netlify.app o sul tuo dominio; Netlify dà TLS e reindirizzamento a HTTPS, ma non header di sicurezza, e le variabili d'ambiente di produzione si configurano nel suo pannello, non nel .env del progetto.

Supabase è tuo

L'integrazione di Supabase crea tabelle, policy e funzioni dalla chat. RLS, bucket e impostazioni di Auth restano responsabilità tua, e Bolt commette gli stessi errori di Lovable con le policy. La guida alla sicurezza per Supabase ha tre query SQL per fare l'audit del progetto in un minuto.

Parte 2: i difetti che Bolt mette nel tuo codice

  • Chiavi segrete nei componenti. Una chiamata a OpenAI o Stripe da React con la chiave dentro. Cerca sk_, service_role e Bearer nel tuo bundle pubblicato.
  • Tabelle senza RLS o con policy using (true). Quando una query fallisce per permessi, il modello apre la policy invece di sistemarla.
  • Edge Functions senza autenticazione. Il template risponde a chiunque con Access-Control-Allow-Origin: *; se la funzione spende soldi, chiunque può spenderli.
  • Controlli solo nell'interfaccia. La pagina di amministrazione si nasconde se non sei amministratore, ma l'API risponde lo stesso.
  • Source map in produzione. Alcuni template di Vite portano build.sourcemap: true; pubblica il tuo codice originale accanto a quello minificato.
  • Invisibile all'IA e ai motori di ricerca. L'HTML arriva vuoto e i bot di ChatGPT o Perplexity non vedono nulla. Se la landing conta, prerenderizzala o separala. Dettaglio in perché le app create con l'IA sono invisibili all'IA.
  • Senza header di sicurezza. Né CSP, né HSTS, né X-Frame-Options. Su Netlify si aggiungono con un file.

Un blocco perché Bolt lo applichi sempre

Bolt legge il file .bolt/prompt del tuo progetto come istruzioni permanenti. Crea il file e incolla questo:

Regole di sicurezza di questo progetto:
- Non mettere mai chiavi segrete nel codice del frontend né in variabili VITE_. Le integrazioni con chiavi segrete vanno in una Edge Function di Supabase o in una funzione di Netlify che legge la chiave dalle sue variabili d'ambiente.
- Ogni tabella nuova ha RLS attivo e una policy esplicita per operazione. Non usare using (true) né with check (true) se non su contenuto pubblico in sola lettura, e avvisami quando lo fai.
- Ogni funzione server verifica il JWT dell'utente, limita Access-Control-Allow-Origin al nostro dominio e valida l'input.
- I permessi di amministratore si controllano in RLS o sul server, mai solo nell'interfaccia.
- I file degli utenti vanno in bucket privati con policy e URL firmati.
- build.sourcemap resta disattivato in produzione.
- Metti titolo, meta description e tag Open Graph reali in index.html.

E gli header per Netlify, in un file public/_headers che viene pubblicato con l'app:

/*
  Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
  X-Content-Type-Options: nosniff
  X-Frame-Options: DENY
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()

Un prompt di revisione prima del deploy

Rivedi la sicurezza di questo progetto e non cambiare ancora nulla. Rispondi con una lista:
1. Chiavi o token nel codice del frontend o in variabili VITE_, con file e riga.
2. Tabelle senza RLS e policy con using (true) o with check (true).
3. Funzioni server che non verificano il JWT, che rispondono con Access-Control-Allow-Origin: * o che non validano l'input.
4. Azioni di amministratore protette solo nell'interfaccia.
5. Bucket pubblici con file degli utenti.
6. build.sourcemap attivo e assenza del file _headers.
7. Metadati di index.html ancora quelli del template.
Per ogni punto, proponi la modifica esatta e aspetta la mia conferma.

Verifica il risultato dall'esterno

curl -sI https://tuodominio.com | grep -iE "strict-transport|x-frame|x-content-type"
curl -s https://tuodominio.com | grep -oE '/assets/[^"]+\.js' | head -1
curl -s https://tuodominio.com/assets/index-XXXX.js | grep -oE "sk_live_[A-Za-z0-9]+|service_role|eyJhbGciOi[A-Za-z0-9_-]{20,}" | head -3
curl -sI https://tuodominio.com/assets/index-XXXX.js.map | head -1

L'atteso: header presenti, nessuna chiave nel chunk e un 404 sulla source map. Poi prova l'API di Supabase senza sessione come spiega la guida Supabase. Scanaris fa queste verifiche e una quarantina di altre in 30 secondi: rileva che l'app è fatta con Bolt, cerca segreti nel bundle, controlla source map, header, CORS, cookie e file esposti, prova le tabelle di Supabase senza sessione e verifica se il tuo contenuto è leggibile senza JavaScript. Per ogni errore ti dà un fix prompt da incollare nella chat di Bolt, e può riscansionare ogni giorno, perché una rigenerazione può riportare un difetto già sistemato.

Domande frequenti

Le variabili VITE_ sono private?

No. Vite incorpora nel bundle tutto ciò che inizia con VITE_; è il suo modo di dire "questo è pubblico". Le chiavi segrete non hanno quel prefisso e non si leggono dal frontend.

Posso impostare header di sicurezza su Netlify?

Sì, con il file _headers nella cartella pubblica o con netlify.toml. Netlify li applica al deploy successivo; verifica con curl.

Cosa faccio se ho incollato una chiave segreta nella chat di Bolt?

Ruotala nel servizio di origine anche se l'hai cancellata dal codice: la cronologia del progetto e i deploy precedenti la conservano. Poi aggiungila nel pannello di Supabase o Netlify e chiedi a Bolt di spostare l'integrazione in una funzione.

Controlli correlati

La tua app Bolt supera questi controlli?

Scansionala gratis e ottieni un prompt di fix per ogni problema che troviamo.

Scansiona il mio sito gratis