Il codice generato da IA funziona. Si esegue. Ha l'aspetto giusto. Viene anche spedito con gli stessi cinque difetti di sicurezza in quasi ogni progetto. Questi non sono rischi teorici — sono i buchi specifici che compaiono in quasi ogni codebase prodotto da Claude, Cursor, Replit, o Copilot quando non lo chiedi esplicitamente.

Ho controllato dozzine di progetti vibe-coded negli ultimi anni, e gli stessi cinque errori compaiono in almeno l'80% di loro. Ognuno richiede meno di 30 minuti per essere corretto. Ecco cosa cercare e esattamente come correggerlo.

Fatti Rapidi
Per chi è
Chiunque spedisca codice generato da IA agli utenti o ai clienti
Tempo per correggere tutti e 5
1–3 ore a seconda della complessità
Stack presunto
Next.js/React + Supabase/Firebase + Vercel/Netlify
Gravità
Gli errori #1 e #2 possono esporre i dati dell'utente — correggili prima
Ultimo verificato
Aprile 2026

Errore 1: Chiavi API Hardcoded nel Codice Frontend

Come accade: Dici a Claude "connettiti a Supabase" o "aggiungi pagamenti con Stripe", e genera codice con la chiave API incollata direttamente in un componente React. Il codice funziona perfettamente — e la tua chiave segreta è visibile a chiunque apra gli DevTools del browser e controlli la scheda Network o la fonte JavaScript.

Perché è pericoloso: La tua chiave Supabase service role aggira tutta la sicurezza del database. La tua chiave segreta Stripe consente a qualcuno di addebitare carte o emettere rimborsi. La tua chiave OpenAI consente a qualcuno di accumulare migliaia di costi in chiamate API sul tuo account. I bot scansionano attivamente i repo GitHub pubblici e i siti distribuiti in cerca di chiavi esposte.

La soluzione: Sposta ogni segreto nelle variabili di ambiente. In Next.js, solo le variabili che iniziano con NEXT_PUBLIC_ raggiungono il browser. Qualsiasi chiave che conceda accesso in scrittura, accesso amministratore o accesso finanziario deve essere solo lato server.

Dopo aver spostato le chiavi in .env.local, cerca nei tuoi interi codebase i vecchi valori delle chiavi per assicurarti che siano scomparsi. Poi controlla la cronologia di Git — se la chiave è mai stata sottoposta a commit, è ancora nella cronologia del tuo repo anche se l'hai eliminata. Rigenera (ruota) qualsiasi chiave che sia mai stata esposta, anche brevemente.

Tempo per correggere: 15–30 minuti.

Errore 2: Tabelle Supabase Senza Sicurezza a Livello di Riga

Come accade: L'IA genera query di creazione delle tabelle Supabase e operazioni CRUD, ma non abilita la Sicurezza a Livello di Riga (RLS). Per impostazione predefinita, le tabelle Supabase con RLS disabilitato sono completamente accessibili a chiunque abbia l'URL del progetto e la chiave anon — entrambi pubblici (e dovrebbero esserlo).

Perché è pericoloso: Senza RLS, l'Utente A può interrogare i dati dell'Utente B. Una semplice chiamata fetch dalla console del browser può estrarre ogni riga da ogni tabella. L'intero database è effettivamente pubblico.

Come individuarlo: Vai al dashboard Supabase → Table Editor. Se una tabella mostra "RLS Disabled", hai questo problema. Controlla anche se il codice lato client utilizza la chiave service_role invece della chiave anon — è ancora peggio.

La soluzione: Abilita RLS su ogni tabella. Poi crea policy che corrispondano ai pattern di accesso della tua app. La policy più comune: gli utenti possono solo SELECT, INSERT, UPDATE e DELETE le righe dove auth.uid() = user_id. Verifica accedendo come un utente e tentando di accedere ai dati di un altro utente tramite l'API REST di Supabase.

Tempo per correggere: 30–60 minuti a seconda del numero di tabelle.

Stai traendo valore da questo? Pubblichiamo un approfondimento a settimana su AI tools, flussi di lavoro e guide di sicurezza pratiche. Unisciti ai lettori che lo ricevono per primi →

Errore 3: Nessuna Convalida dell'Input su Form o Route API

Come accade: L'IA genera form che accettano qualsiasi input e route API che si fidano di qualsiasi dato arrivi. Il form ha un attributo "required" in HTML, ma nessuna convalida lato server. Qualcuno aggira il form inviando una richiesta API diretta con qualsiasi payload voglia.

Perché è pericoloso: Senza convalida lato server, gli attaccanti possono iniettare script nel tuo database (XSS archiviato), inviare payload di dimensioni eccessive che bloccano il server o inviare dati che rompono la logica della tua app (come un prezzo negativo o un campo email contenente SQL).

Come individuarlo: Apri qualsiasi route API o server action nel tuo codebase. Se utilizza req.body o dati del form senza controllare la forma, il tipo e la lunghezza di ogni campo, hai questo problema.

La soluzione: Aggiungi convalida lato server a ogni endpoint utilizzando una libreria di convalida dello schema. Zod è lo standard per i progetti TypeScript:

TypeScript
import { z } from 'zod';

const taskSchema = z.object({
  title: z.string().min(1).max(200),
  description: z.string().max(2000).optional(),
  priority: z.enum(['low', 'medium', 'high']),
});

// In your API route:
const parsed = taskSchema.safeParse(req.body);
if (!parsed.success) {
  return Response.json({ error: parsed.error }, { status: 400 });
}

Per qualsiasi campo che si visualizza come HTML (commenti, descrizioni, biografie), igienizza anche l'output con DOMPurify prima di visualizzarlo.

Tempo per correggere: 30–60 minuti.

Errore 4: Nessun Rate Limiting sugli Endpoint API

Come accade: L'IA non aggiunge mai rate limiting a meno che tu non lo chieda. Ogni route API che la tua app espone può essere colpita migliaia di volte al secondo da chiunque abbia uno script.

Perché è pericoloso: Senza rate limiting, qualcuno può attaccare a forza bruta il tuo endpoint di login, raschiare il tuo database colpendo più volte gli endpoint di lista, sovraccaricare il tuo server (negazione del servizio) o bruciare la tua quota API se i tuoi endpoint chiamano servizi esterni come OpenAI o Stripe.

Come individuarlo: Se nessuna delle tue route API controlla quante richieste ha fatto un singolo IP o utente di recente, non hai rate limiting.

La soluzione: L'approccio più semplice per le app ospitate su Vercel è un rate limiter in memoria per lo sviluppo e uno basato su Redis per la produzione. Edge Middleware di Vercel può gestire il rate limiting di base. Upstash Redis (livello gratuito) con @upstash/ratelimit ti offre rate limiting di livello produzione in una piccola quantità di codice.

Un punto di partenza ragionevole: 60 richieste al minuto per gli utenti autenticati, 20 al minuto per gli utenti non autenticati e 5 al minuto per gli endpoint di login/signup (per prevenire attacchi a forza bruta).

Tempo per correggere: 20–45 minuti.

Errore 5: Mancanza di Controlli di Autenticazione su Pagine e API Protette

Come accade: L'IA genera una bellissima pagina dashboard e route API che restituiscono dati dell'utente, ma non aggiunge middleware per verificare che l'utente sia effettivamente connesso. La pagina "funziona" perché durante lo sviluppo sei sempre connesso. In produzione, qualcuno può accedere all'URL del dashboard direttamente senza effettuare l'accesso, o colpire l'endpoint API e ottenere i dati.

Perché è pericoloso: L'accesso non autenticato alle pagine protette significa che chiunque può vedere dashboard utente, pannelli amministratori o dati privati semplicemente indovinando l'URL. Le route API non protette significano che qualsiasi strumento come Postman o curl può estrarre dati senza credenziali.

Come individuarlo: Apri una finestra del browser in incognito (non connesso) e vai direttamente ai tuoi URL dashboard, impostazioni o amministratore. Se puoi vedere contenuti senza essere reindirizzato a una pagina di login, hai questo problema. Poi prova a colpire direttamente le tue route API — se restituiscono dati senza un cookie di sessione valido o un token di autenticazione, quelle non sono protette.

La soluzione: Aggiungi middleware di autenticazione che si esegua prima di ogni route protetta. In Next.js App Router, crea un middleware.ts alla radice del tuo progetto:

TypeScript
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const session = request.cookies.get('session');
  if (!session) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*', '/api/protected/:path*'],
};

Adatta il matcher per coprire ogni route che dovrebbe richiedere autenticazione. Verifica in incognito dopo l'implementazione.

Tempo per correggere: 15–30 minuti.

Come Prevenire Questi nei Progetti Futuri

Il pattern è chiaro: l'IA genera codice che funziona funzionalmente ma salta la sicurezza perché non lo hai chiesto. La soluzione è chiederlo fin dall'inizio.

Aggiungi questo alla fine del tuo prompt iniziale per qualsiasi progetto vibe-coded:

Snippet prompt
SECURITY REQUIREMENTS:
- All secrets in environment variables (never hardcoded)
- Supabase RLS enabled on all tables with per-user policies
- Server-side input validation on every API route (use Zod)
- Rate limiting on all public endpoints
- Authentication middleware on all protected routes
- No service role key in client-side code

Non catturerà tutto, ma elimina i cinque difetti di sicurezza più comuni al primo passaggio invece di richiedere una pulizia in seguito.

Se vuoi migliorare la scrittura di prompt che producono codice più sicuro dall'inizio, il nostro ottimizzatore di prompt gratuito può aiutarti a strutturare le tue istruzioni. E per una guida di sicurezza completa, vedi la nostra guida passo passo: Come Proteggere un'App Vibe-Coded Prima di Darla ai Clienti.

Questo è quello che facciamo ogni settimana. Un approfondimento su AI tools, flussi di lavoro e opinioni oneste — niente hype, niente riempitivo. Unisciti a noi →

Disclosure: Alcuni link in questo articolo sono link di affiliazione. Consigliamo solo strumenti che abbiamo testato personalmente e usiamo regolarmente. Vedi la nostra politica di divulgazione completa.