VibeInspect.aiBlog

AI che decide il routing: se manca il filtro di policy, il tuo repo è esposto

VibeInspect.ai · 27 agosto 2026 · 5 min di lettura

  • autorizzazione
  • cursor
  • vibe-coding
  • sicurezza
  • audit

Un modello AI può raccomandare, ma è la policy a dover decidere

Un pattern architetturale pubblicato su dev.to descrive un router di messaggi "assistito" da AI costruito su SQS, Lambda e Amazon Bedrock. L'autore chiarisce il principio in modo netto: "AI recommends. Policy decides. The messaging platform executes." (Building an AI-Assisted Message Router with SQS, Lambda, and Amazon Bedrock).

Il dettaglio che conta per te non è l'eleganza del diagramma. È una frase apparentemente marginale: i vincoli di policy, come le restrizioni di sicurezza o residenza dei dati, dovrebbero filtrare le destinazioni non valide prima che il modello assegni un punteggio. In altre parole: il modello non deve mai poter proporre una rotta che le regole di business vietano. La validazione (ALLOWED_ROUTES, soglia di confidenza, fallback deterministico) viene prima dell'azione, non dopo.

Sembra ovvio scritto così. Nella pratica, in un repository generato in fretta con un assistente AI, quel filtro spesso non esiste. Il modello propone, il codice esegue, e nessuno controlla che l'output rientri in un insieme di scelte autorizzate.

Cosa significa se il tuo codice l'ha scritto Cursor

Quando chiedi a Cursor di collegare una coda, un webhook o un handler che smista richieste in base a un input, ottieni codice che funziona nel percorso felice. Il messaggio arriva, viene instradato, il test passa. Ma il problema di autorizzazione vive esattamente dove Cursor tende a saltare: nel confine tra "ciò che è stato richiesto" e "ciò che è permesso".

Se il tuo handler prende una destinazione, un tenant o un ruolo direttamente dal payload e lo usa per decidere dove va il messaggio o a quali dati accede, senza confrontarlo con una lista autorizzata lato server, hai un problema di autorizzazione. Non importa che a decidere sia un modello Bedrock o un semplice if: se il valore in ingresso governa un'azione senza un filtro di policy, chiunque possa manipolare quel valore può instradarsi dove non dovrebbe.

Cursor non conosce le tue regole di business. Non sa che il tenant A non deve mai finire nella coda del tenant B, o che una richiesta "critical" non può bypassare la validazione. Genera codice plausibile, non codice che rispetta i tuoi confini. E un confine di autorizzazione mancante non produce un errore: produce un sistema che obbedisce a input che non avrebbe mai dovuto accettare.

Perché ora ti serve un audit

Il motivo per cui un problema di autorizzazione resta nascosto è semplice: non rompe niente. L'app si avvia, gli utenti legittimi fanno cose legittime, i log sono puliti. Il difetto emerge solo quando qualcuno invia un valore fuori dall'insieme previsto, e a quel punto non è più un bug: è un accesso non autorizzato.

Un audit di VibeInspect serve proprio a rendere osservabile ciò che oggi non lo è. Carichi lo ZIP del repository, degli specialisti AI analizzano il codice e ricevi un PDF con un verdetto. Nessun server: il sorgente viene cancellato al termine dell'analisi.

Qui il verdetto che ti serve è concreto: dove un valore proveniente dall'esterno decide un'azione senza passare per un controllo di autorizzazione lato server. Non "il tuo codice è sicuro al 100%" — quella promessa non esiste. Piuttosto: quali punti del tuo instradamento, delle tue query o dei tuoi handler accettano un input come se fosse già autorizzato.

Con il piano Diagnostic ottieni file, riga ed evidenza del punto in cui manca il filtro. Non correggiamo il codice al posto tuo e non c'è revisione umana in questa fase: ricevi le evidenze, la decisione e la patch restano nelle tue mani. È l'equivalente pratico del principio della fonte: il modello raccomanda, ma sei tu a decidere cosa è permesso — e per decidere devi prima sapere dove il permesso oggi non viene verificato.

Cosa un linter non vede

Un linter controlla la forma. Ti segnala una variabile non usata, un import mancante, una parentesi fuori posto, magari uno stile non conforme. È utile, ma è cieco rispetto alla logica di autorizzazione.

Un linter non sa che route = payload["destination"] è pericoloso. Sintatticamente è perfetto. Non sa che quella destinazione dovrebbe appartenere a un insieme ALLOWED_ROUTES verificato lato server. Non sa che il tenant_id letto dal body dovrebbe corrispondere all'utente autenticato, non arrivare libero dal client. Non sa che il fallback deterministico manca del tutto e che, quando l'input è inatteso, il tuo sistema fa qualcosa di imprevedibile invece di rifiutare in modo sicuro.

Il confine tra input e azione è una questione di significato, non di sintassi. Ecco perché un audit orientato alle conseguenze vede cose che nessun linter può cogliere: guarda cosa fa il codice con un valore non fidato, non se è scritto in modo ordinato. Un IDOR o un bypass di autorizzazione superano tutti i linter del mondo, perché sono codice formalmente corretto che si fida della persona sbagliata.

Cosa fare questa settimana

Dedica un'ora a cercare i punti in cui un valore esterno guida un'azione. Parti dai tuoi handler di routing, dai webhook e dalle query che usano un ID passato dal client.

  1. Cerca gli input che decidono. Trova ogni punto in cui una destinazione, un ruolo, un tenant o un ID arriva dal payload e governa un'azione o un accesso.
  2. Verifica il filtro. Per ciascuno, chiediti: questo valore viene confrontato con un insieme autorizzato lato server prima di essere usato? Se la risposta è no, hai trovato un candidato.
  3. Controlla il fallback. Quando l'input è fuori dall'insieme previsto, il sistema rifiuta in modo sicuro o fa qualcosa a caso?
  4. Ottieni un verdetto sulle evidenze. Se sospetti che il filtro manchi in più punti e vuoi file e riga precisi, esegui un audit Diagnostic su VibeInspect.

Il principio della fonte vale anche fuori da Bedrock: qualcosa raccomanda o richiede, ma è la tua policy a dover decidere. Se nel tuo repo quella policy non c'è, questa è la settimana giusta per scoprirlo.

Domande frequenti

Un problema di autorizzazione mandato in produzione da un assistente AI si nota subito?

No. Nel percorso normale tutto funziona: l'app parte, gli utenti legittimi lavorano, i log sono puliti. Il difetto emerge solo quando qualcuno invia un valore fuori dall'insieme previsto, e a quel punto è un accesso non autorizzato, non un semplice bug.

Perché un linter non individua un controllo di autorizzazione mancante?

Il linter verifica la forma del codice, non il significato. Una riga come route = payload["destination"] è sintatticamente perfetta, ma il linter non sa che quel valore dovrebbe essere confrontato con un insieme autorizzato lato server prima di essere usato.

Cosa mi dà VibeInspect rispetto a un test manuale?

Carichi lo ZIP del repository e ricevi un PDF con un verdetto sui punti in cui un input esterno decide un'azione senza controllo di autorizzazione. Con il piano Diagnostic ottieni file, riga ed evidenza. Non correggiamo il codice e non è un pentest.

VibeInspect conserva il mio codice sorgente?

No. L'analisi avviene senza mantenere un server e il codice sorgente viene cancellato al termine. Ricevi il verdetto in PDF, non lasci il repository in giro.