← Torna al blog
Vibe CodingScanaris Team · 6 min di lettura · October 04, 2026

Sicurezza quando fai il deploy su Vercel

Vercel rende il deploy così facile che ci si dimentica che resta un server su internet. La piattaforma in sé è ben protetta: TLS automatico, rete globale, isolamento tra progetti. I buchi li mettiamo noi nella configurazione, e sono quasi sempre gli stessi cinque o sei. Questa guida li ripassa uno per uno con il comando per verificarli e la modifica esatta per chiuderli, pensando ad app generate con Cursor, Bolt o v0 che finiscono su Vercel.

1. Variabili d'ambiente che finiscono nel browser

Su Vercel definisci le variabili nel pannello del progetto, e il framework decide quali arrivano al client. In Next.js, tutto ciò che inizia con NEXT_PUBLIC_; in Vite, con VITE_; in Nuxt, ciò che sta sotto runtimeConfig.public. È una convenzione utile finché qualcuno non mette NEXT_PUBLIC_STRIPE_SECRET_KEY perché l'IA doveva accedervi da un componente. Quella chiave viaggia nel bundle verso tutti i visitatori.

Due abitudini lo evitano. Primo, controllare il prefisso: se una variabile ha il prefisso pubblico, assumi che sia pubblica e chiediti se dovrebbe esserlo. Secondo, usare gli ambienti di Vercel (Production, Preview, Development) perché le chiavi di produzione non esistano nei branch di test, e marcare quelle sensibili come Sensitive, che impedisce di vederle dopo dal pannello. Per verificare cosa è arrivato nel bundle:

curl -s https://tuodominio.com/ | grep -o '/_next/static/chunks/[^"]*\.js' | sort -u | head -20

Scarica quei file e cerca sk_live, service_role, AKIA o il nome delle tue variabili. Di più in segreti che la tua app fa trapelare nel browser.

2. Deploy di anteprima pubblici

Ogni branch e ogni pull request genera un URL del tipo progetto-git-branch-team.vercel.app. È comodo per mostrare le modifiche, ed è pubblico: chiunque abbia l'URL vede la versione in sviluppo, con le sue funzionalità a metà e, a volte, i suoi dati di prova. Vercel aggiunge di default un header perché i motori di ricerca non indicizzino le anteprime, ma questo non impedisce a una persona di aprirla.

La soluzione sta in Settings, Deployment Protection: attiva Vercel Authentication perché solo i membri del team accedano alle preview (è disponibile nel piano gratuito), o la protezione con password nei piani a pagamento. E ricorda che l'URL progetto.vercel.app di produzione esiste anche accanto al tuo dominio: reindirizzalo al tuo dominio o metti un canonical perché non competa con te su Google.

3. Header di sicurezza che nessuno ha messo

Vercel serve la tua app con gli header minimi; quelli di sicurezza li devi aggiungere tu. Senza, il tuo sito può essere incorporato in un iframe altrui, il browser indovina i tipi di contenuto e non c'è una policy che limiti quali script vengono eseguiti. In vercel.json si aggiungono così:

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" },
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "X-Frame-Options", "value": "DENY" },
        { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
        { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
      ]
    }
  ]
}

In Next.js puoi farlo anche da next.config.js con la funzione headers(). La Content-Security-Policy merita un passaggio a parte perché va adattata ai tuoi script; la spiegazione di ogni header è in header di sicurezza HTTP spiegati per umani, e puoi verificare i tuoi con l'analizzatore di header.

4. Source map pubblicate

Le source map permettono di vedere il codice originale invece di quello minificato. Sono utili per il debug e una pessima idea in produzione: regalano la tua logica, le tue rotte interne e i commenti con "TODO: togliere questa chiave". Next.js le disattiva di default nel browser (productionBrowserSourceMaps: false); in Vite dipende da build.sourcemap, che alcuni template mettono a true. Verifica se esistono:

curl -sI https://tuodominio.com/_next/static/chunks/main-abc123.js.map | head -1

Se risponde 200, sono pubblicate. Se ti servono le map per tracciare gli errori, caricale sul tuo servizio di monitoraggio in fase di build e non servirle al pubblico.

5. File e rotte che non dovrebbero rispondere

Tutto ciò che sta nella cartella public/ viene servito così com'è. Un .env copiato lì per errore, un backup.json, un config.yml con credenziali: pubblici. Anche le rotte API contano: /api/debug, /api/seed o /api/admin che l'IA ha creato per provare e che restano in produzione senza autenticazione. E le rotte cron: Vercel le chiama con un header Authorization che contiene il tuo CRON_SECRET; se non lo verifichi nel codice, chiunque può lanciare il tuo task programmato.

for p in .env .env.local .git/config config.json backup.zip api/debug api/seed; do
  printf "%s -> " "$p"; curl -s -o /dev/null -w "%{http_code}\n" "https://tuodominio.com/$p"
done

Tutto ciò che risponde 200 merita un'occhiata.

6. Funzioni senza limiti

Una rotta API che chiama OpenAI o invia email senza limitare le richieste è una fattura in attesa di essere scoperta. Vercel ha un firewall con regole di rate limit per IP e una modalità di sfida contro i bot che si attiva dal pannello senza toccare il codice. Per gli endpoint che costano, aggiungi anche un limite per utente nella tua logica e richiedi la sessione.

7. CORS e cookie nelle rotte API

Se la tua API risponde con Access-Control-Allow-Origin: * e in più usa cookie, qualsiasi sito può fare richieste a nome dei tuoi utenti. Su Vercel si configura per rotta in vercel.json o nell'handler stesso. Elenca le origini permesse in modo esplicito e non combinare mai il wildcard con le credenziali. Dettaglio in CORS configurato male.

8. Quello che Vercel fa già per te

Per non farti perdere tempo: il certificato TLS viene emesso e rinnovato da solo, HTTP reindirizza a HTTPS automaticamente, le funzioni girano isolate e i log di deploy restano tracciati. Quello che non fa è decidere per te cosa è pubblico, quali header invii né chi può vedere le tue preview. Quella parte è tua.

Checklist di cinque minuti

  • Nessuna variabile con prefisso pubblico contiene una chiave segreta.
  • Deployment Protection attiva per le anteprime.
  • Header di sicurezza in vercel.json o next.config.js.
  • Source map non accessibili in produzione.
  • Nulla di sensibile in public/; rotte di test eliminate; cron protetto con il suo segreto.
  • Rate limit sulle rotte che costano.
  • CORS con origini esplicite.
  • L'URL .vercel.app reindirizza al tuo dominio.

Scanaris lo verifica per te

Scanaris controlla dall'esterno il tuo deploy su Vercel: header, segreti nel bundle, source map, file e rotte esposte, CORS, cookie e TLS, e ti dà un fix prompt per ogni errore da incollare in Cursor, Bolt o v0 con la modifica esatta in vercel.json o nel tuo codice. Sono controlli in sola lettura su ciò che è già pubblico; non tocca mai il tuo progetto. I rischi specifici della piattaforma sono nella guida alla sicurezza per Vercel, e se la tua app è Next.js, nella checklist Next.js.

Domande frequenti

Le anteprime di Vercel sono private di default?

No. Sono pubbliche per chiunque abbia l'URL, anche se non vengono indicizzate dai motori di ricerca. Attiva Vercel Authentication in Deployment Protection per limitarle al tuo team.

Vercel mette gli header di sicurezza automaticamente?

Solo quelli di base per il funzionamento. HSTS, X-Frame-Options, Content-Security-Policy e il resto li devi configurare tu in vercel.json o nel framework.

Cosa succede se una chiave segreta è già stata pubblicata con prefisso pubblico?

Considerala compromessa anche se la togli dal codice: il bundle precedente può essere in cache o scaricato. Ruota la chiave nel servizio di origine, spostala in una variabile senza prefisso e fai di nuovo il deploy.

Come se la cava il tuo sito?

Lascia che Scanaris lo analizzi e verifica in 30 secondi, gratis.

Scansiona il mio sito

Controlli correlati

Guide di sicurezza per stack