Cosa guarda davvero un reviewer umano sul codice generato da AI
Una pull request generata con AI può essere ordinata, leggibile e piena di test verdi. Può seguire lo stile del progetto, aggiornare la documentazione, correggere bug visibili e chiudere una feature in poche ore. Il problema è che la sicurezza non si valuta guardando se il codice compila o se la demo funziona: serve capire cosa è cambiato davvero nel comportamento dell’applicazione.
Una Secure Code Review su codice generato o modificato da AI non cerca “errori dell’AI” in astratto. Legge il diff dentro il prodotto: quali dati vengono toccati, quali route sono esposte, quali ruoli possono eseguire azioni, quali query cambiano, quali segreti entrano nel perimetro, quali dipendenze sono state aggiunte, quali test sono stati modificati e quale configurazione andrà in produzione.
Per developer, CTO e software house, il punto critico è questo: il codice AI-generated può essere plausibile anche quando introduce una regressione di sicurezza. Una review umana serve a collegare codice, business logic, trust boundary, deploy e rischio reale prima che il merge diventi una vulnerabilità in produzione.
Perché una review funzionale non basta
La review funzionale chiede se la feature fa ciò che era richiesto. La Secure Code Review chiede anche cosa può essere abusato, quali assunzioni sono cambiate e quali controlli sono stati indeboliti. Questa differenza conta molto quando il codice è stato generato da AI, perché l’assistente tende a ottimizzare per completare il task, non per preservare confini di sicurezza non esplicitati nel prompt.
Un reviewer umano legge il codice con domande diverse da quelle della demo: cosa succede se l’utente cambia un ID, se il token è scaduto, se il ruolo è basso, se il tenant è diverso, se l’upload contiene un file inatteso, se una dipendenza esegue script, se una variabile privata finisce nel frontend, se la pipeline salta un controllo.
Gli scanner aiutano, ma non sostituiscono questa lettura. SAST, dependency scanning, secret scanning e lint intercettano pattern utili, ma non comprendono sempre business logic, tenant isolation, stati del workflow, abuso di funzioni legittime, semantica dei ruoli o impatto di un refactoring multi-file.
Il primo controllo: cosa ha cambiato davvero la PR
Le PR AI-generated possono essere ampie: un prompt chiede “aggiungi questa feature” e l’agente modifica route, componenti, middleware, test, schema dati, dipendenze, configurazioni e documentazione. Il diff è coerente, ma il reviewer deve separare feature, refactoring, test e cambiamenti di sicurezza.
La prima attività è classificare i file toccati. Controller, API route, server actions, middleware, query, migration, policy, file .env.example, workflow CI/CD, Dockerfile, package manager, lockfile, storage policies, auth config e test non hanno lo stesso peso. Una modifica piccola a middleware o CORS può essere più rischiosa di cento righe di UI.
Quando il diff è troppo grande, va ridotto o spezzato. Una review efficace significa poter dire: questo commit cambia logica applicativa, questo cambia presentazione, questo cambia dipendenze, questo cambia deploy. Se tutto è mescolato, il rischio di accettare una regressione aumenta.
Trust boundary: dove il codice smette di potersi fidare
Un reviewer umano cerca i confini di fiducia. Il browser non è trusted, il body di una richiesta non è trusted, e lo stesso vale per header, query string, local storage, ruoli inviati dal client, file caricati e output di un modello. Anche un servizio interno può essere meno trusted di quanto sembri se riceve input da utenti o integrazioni esterne.
Il codice generato dall’AI può attraversare questi confini senza marcarli: può usare user_id dal client invece dell’utente in sessione, costruire una query con parametri non validati, trattare un claim del token come permesso finale senza controllo applicativo, oppure passare output di un LLM a HTML, SQL, shell, ticket, email o tool downstream.
In review, ogni trust boundary deve produrre una domanda precisa: chi controlla questo dato, dove viene validato, dove viene autorizzato, dove viene loggato, cosa succede se il valore è manipolato. Se la risposta non è nel codice, il comportamento non è verificabile.
Auth, ruoli e autorizzazioni lato server
Una delle aree più importanti è l’access control. Il reviewer controlla se le nuove route richiedono login, se verificano ruolo, ownership e tenant, se applicano il middleware corretto e se non delegano decisioni di sicurezza alla UI. Un’app può mostrare pulsanti corretti ma avere API chiamabili direttamente.
La review deve seguire le route sensibili: lettura dati, modifica, cancellazione, export, upload, inviti, cambio ruolo, funzioni admin, billing, refund, approvazioni e impersonificazione. Per ciascuna, il codice deve rispondere a chi può chiamarla, su quali oggetti, in quale stato e con quali limiti.
Nel codice AI-generated, i pattern sospetti più comuni sono: if (user) senza controllo ruolo, query per ID senza ownership, tenant_id preso dal body, isAdmin letto dal client, middleware non applicato a nuove route, test che verificano solo l’utente corretto. Questi problemi spesso non emergono dalla demo.
Business logic e workflow fuori sequenza
La business logic è una delle ragioni principali per cui serve una review umana. Un agente può implementare bene i singoli step e non proteggere la sequenza: un invito scaduto può essere riusato, un ordine può essere modificato dopo il pagamento, un refund può essere chiamato da un ruolo sbagliato, una richiesta può essere approvata due volte, un export può includere dati fuori perimetro.
Il reviewer cerca invarianti: cosa deve essere sempre vero? Un ordine pagato non cambia prezzo. Un documento di un tenant non appare in un altro tenant. Un utente sospeso non genera API key. Un link monouso non può essere riutilizzato. Un pagamento non può essere confermato solo perché il frontend ha mostrato successo.
La review del codice deve leggere anche gli stati, non solo le funzioni. Se il codice modifica status, ruoli, pagamenti, quote, limiti, inviti o autorizzazioni, servono controlli di stato, idempotenza e casi negativi.
Query, ORM e access layer
Molte vulnerabilità nel codice AI-generated non sono nella sintassi, ma nella query. Un ORM rende il codice leggibile, ma non impedisce query senza tenant filter, join troppo ampi, condizioni mancanti o filtri applicati dopo aver recuperato i dati. Una funzione può caricare tutti i record e filtrare lato client o lato applicazione in modo incompleto.
Il reviewer controlla dove vengono applicati ownership, ruolo e tenant: nella query, nel service layer, nella policy database o nel controller. Se il filtro è duplicato in molte route, aumenta il rischio che una nuova route generata dall’AI lo dimentichi. Se la service key bypassa le policy e il codice non filtra, il database diventa esposto attraverso il backend.
Vanno letti anche migration e seed: l’AI può aggiungere colonne sensibili, cambiare default, creare indici su dati personali, rendere nullable un campo critico o introdurre tabelle temporanee che poi restano in produzione. Il modello dati è parte della superficie di sicurezza.
Input validation, output handling e upload
Il codice generato da AI spesso gestisce bene l’input previsto dal form. La review deve guardare gli input non previsti: JSON body manipolato, query string, header, path parameter, file upload, MIME type falsificato, filename, markdown, HTML, valori numerici fuori range, array troppo grandi, oggetti annidati e payload parziali.
La validazione deve essere server-side e coerente con la logica di dominio. Se una quantità deve essere positiva, se un ruolo può avere solo alcuni valori, se un file deve essere PDF, se una data non può essere nel passato, questi vincoli non possono vivere solo nel form frontend.
Anche l’output va letto. HTML non escaped, messaggi di errore verbosi, stack trace, query, path interni, token, dettagli database e dati di altri utenti possono uscire da response, log, export o template email. Una review sicura controlla sia cosa entra sia cosa esce.
Segreti, configurazioni e log
Una Code Review su codice AI-generated cerca segreti in posti ordinari e non ordinari: sorgenti, test, .env.example, README, Dockerfile, workflow, script, log, seed, fixture, config cloud, source map e bundle frontend. L’AI può copiare una chiave “temporanea” in un punto che poi arriva al deploy.
La review non si limita a dire “spostalo in env”. Verifica se quel segreto è già uscito, se va ruotato, se è pubblico o privato, se ha scope minimo e se può finire nel client. Una service role key, un database URL o un token cloud nel posto sbagliato possono avere impatto immediato.
Logging ed error handling sono altre aree sensibili. Durante il debug, l’AI può aggiungere log molto verbosi e lasciarli nel codice: il reviewer controlla che in produzione non vengano stampati payload, token, query, PII, path interni, stack trace completi o dati cliente.
Dipendenze e supply chain nel diff
Quando l’AI incontra un errore, spesso propone una libreria. Questo può essere corretto, ma ogni nuova dipendenza entra nella superficie del prodotto. Package quasi omonimi, librerie poco mantenute, licenze non compatibili, script postinstall, dipendenze transitive vulnerabili e lockfile modificati vanno letti con attenzione.
Il reviewer confronta la necessità reale con il costo di introdurre il pacchetto: esiste già una libreria nel progetto, la dipendenza è mantenuta, ha CVE note, esegue script, cambia parsing, auth, crypto, upload, sanitizzazione, template o rete, il lockfile mostra più cambi del previsto.
Per il codice AI-generated, è importante leggere anche ciò che viene rimosso. Sostituire una libreria può eliminare controlli impliciti, aggiornare un framework può cambiare default di sicurezza e spostare una funzione in un pacchetto “più semplice” può perdere validazioni già presenti.
Test generati dall’AI: cosa confermano e cosa non sfidano
I test scritti dall’AI tendono a confermare il comportamento implementato. Sono utili, ma spesso coprono il percorso felice: input corretto, ruolo corretto, stato corretto, risposta prevista. Una Secure Code Review guarda anche il diff dei test per capire se sono stati indeboliti.
Segnali da controllare: test rimossi, assertion meno precise, mock troppo permissivi, casi negativi mancanti, snapshot aggiornati senza spiegazione, test di autorizzazione assenti, errori gestiti come successo, coverage che sale ma non copre i trust boundary.
Per ogni area sensibile servono test negativi: utente sbagliato, tenant sbagliato, token scaduto, ruolo basso, input malevolo, file non valido, stato fuori sequenza, richiesta duplicata, limite superato. Se un bug di sicurezza viene trovato, deve diventare regressione in pipeline.
Configurazioni, CI/CD e deploy
Una PR AI-generated può modificare anche ciò che manda il codice in produzione: Dockerfile, workflow CI/CD, variabili ambiente, CORS, security headers, debug mode, logging, IaC, cloud permissions, deploy script, branch protection, test gate. Questi file non sono “contorno”.
Il reviewer cerca semplificazioni pericolose: test disabilitati, SAST rimosso, secret scanning aggirato, debug attivo, CORS *, CSP indebolita, token con scope più ampio, deploy automatico da branch non protetto, log più verbosi, environment di staging collegato a produzione.
Se una modifica di config è necessaria, deve essere esplicita e proporzionata. Una build che passa perché i controlli sono stati spenti non è una release più stabile: è una release meno osservabile.
Prompt, rules file e istruzioni persistenti
Quando il progetto usa Cursor rules, AGENTS.md, istruzioni Claude, prompt di progetto o file simili, la review deve includerli se influenzano il codice generato. Queste istruzioni possono orientare stile, librerie, test, sicurezza, deploy e decisioni dell’agente.
Un file di regole può contenere indicazioni utili, ma anche scorciatoie pericolose: “disabilita i controlli in dev”, “usa questa chiave”, “ignora test flaky”, “non chiedere conferma”, “usa policy permissive”. Se l’agente segue quelle istruzioni, il rischio entra nella PR anche se il file sembra documentazione.
Il reviewer controlla se le istruzioni persistenti sono coerenti con il livello di responsabilità del progetto. Per team che usano AI coding in modo continuativo, queste regole diventano parte del processo di sviluppo e meritano ownership esplicita.
Come leggere una PR AI troppo grande
Quando una PR generata da AI è troppo ampia, il reviewer deve ricostruire una sequenza che spesso il diff non racconta bene. Prima si individua il comportamento nuovo: quale feature è stata aggiunta, quale bug è stato corretto, quale flusso cambia. Poi si separano le modifiche di supporto: refactoring, spostamento file, rename, aggiornamento test, dipendenze, configurazioni.
Il passaggio successivo è isolare le aree ad alta responsabilità. Anche in una PR enorme, alcuni file pesano più di altri: middleware, route API, auth provider, query, migration, secret handling, file di deploy, workflow CI/CD, policy database, funzioni server-side e logica di pagamento. La review deve partire da lì, non dai componenti visuali più facili da leggere.
Se la PR modifica insieme UI, API, database e deploy, chiedere una separazione può essere una decisione di sicurezza. Non è burocrazia: serve a evitare che un cambiamento su CORS, un nuovo pacchetto, una policy più permissiva o una query senza tenant filter restino nascosti dentro una feature apparentemente innocua.
Per le software house, questa disciplina è ancora più importante. Una PR AI consegnata al cliente deve poter essere spiegata: cosa è cambiato, quali file sono stati generati, quali assunzioni sono state accettate, quali test dimostrano che i confini sono rimasti corretti. Se non si riesce a spiegare il diff, è difficile difenderne la sicurezza.
Cosa deve uscire dalla review: finding e remediation
Una Code Review utile non produce solo una lista di problemi. Deve trasformare il diff in decisioni: cosa blocca il merge, cosa va corretto prima del deploy, cosa può essere pianificato, quali test vanno aggiunti e quali rischi restano accettati con owner. Questo è particolarmente importante con codice AI-generated, perché lo stesso pattern può ripetersi in PR successive.
I finding vanno descritti con contesto applicativo. “Manca controllo autorizzativo” è meno utile di “l’endpoint export usa l’ID del tenant ricevuto dal client e consente a un utente autenticato di esportare dati di un altro workspace”. La seconda formulazione permette a developer, CTO e PM di capire impatto, priorità e remediation.
La remediation deve preferire correzioni strutturali. Se un endpoint manca di tenant isolation, correggere solo quella route può non bastare: potrebbe servire un helper centralizzato, una policy database, un test negativo e una regola di review per le nuove route. Se una dipendenza è stata aggiunta senza motivo, il fix può essere rimuoverla, sostituirla con una libreria già approvata o bloccare installazioni automatiche senza review.
Il report finale dovrebbe indicare almeno: perimetro revisionato, file e commit considerati, aree escluse, finding bloccanti, finding pianificabili, test suggeriti, evidenze di fix, rischi residui e raccomandazioni per le prossime PR AI. Questo rende la review riutilizzabile, non solo correttiva.
Quando serve una Code Review indipendente
Una review interna può bastare per modifiche piccole, isolate, senza dati reali, senza ruoli, senza API esposte e con reviewer esperti sulle aree toccate. Serve una Code Review indipendente quando la PR generata da AI modifica auth, autorizzazioni, query, database, segreti, dipendenze, deploy, CI/CD, cloud, pagamenti, upload, workflow o logica di business critica.
Serve anche quando il diff è troppo ampio da capire, quando il team ha accettato molte proposte “Accept All”, quando gli scanner sono puliti ma il rischio è nella logica applicativa, o quando una software house deve consegnare codice a un cliente e vuole evidenze di controllo prima del rilascio.
La Code Review non rallenta la velocità dell’AI coding: evita che la velocità sposti il costo a dopo il go-live. Un finding corretto prima del merge costa meno di una regressione su dati, ruoli o deploy in produzione.
Come ISGroup può verificare codice generato o modificato da AI
ISGroup può eseguire una Code Review mirata sulle aree ad alto rischio del codice AI-generated: diff, auth, access control, business logic, query, segreti, logging, dipendenze, configurazioni, test e pipeline. Il perimetro può essere una singola PR, una feature, un modulo, un repository o un flusso pre go-live.
| Se il codice AI ha modificato… | Rischio principale | Controllo consigliato |
|---|---|---|
| Auth, ruoli, middleware, query, API, business logic, segreti o dipendenze | Vulnerabilità nel codice e regressioni applicative | Code Review |
| Web app, API, upload, export o flussi esposti online | Comportamenti abusabili dall’esterno | Web Application Penetration Testing |
| CI/CD, policy di review, branch protection, test gate e uso continuativo di agenti | Controlli non ripetibili sulle release | Software Assurance Lifecycle |
| Cloud, IaC, IAM, bucket, database, env e deploy | Misconfiguration o privilegi eccessivi | Cloud Security Assessment |
| Servizi, host o componenti esposti con versioni e configurazioni note | Vulnerabilità note e superfici tecniche | Vulnerability Assessment |
La scelta del controllo dipende da cosa è stato toccato. Per codice AI-generated, Code Review e WAPT sono spesso complementari: la review trova la causa nel codice, il test applicativo dimostra il comportamento reale.
Hai una PR o una feature generata con AI che tocca dati, API, ruoli, dipendenze o deploy? ISGroup può eseguire una review mirata prima del merge o del go-live.
Evidenze da preparare
Prepara repository, branch, PR, descrizione della feature, prompt o istruzioni rilevanti, elenco dei file modificati, test eseguiti, parti generate da AI, dipendenze aggiunte, configurazioni cambiate, ambienti coinvolti e rischi già noti.
Per una review efficace servono anche dati di contesto: ruoli utente, trust boundary, API esposte, schema dati, provider auth, database, storage, pipeline, variabili ambiente, servizi cloud e flussi critici. Il codice non parla da solo quando la vulnerabilità dipende dal dominio.
Se la PR è ampia, conviene indicare cosa deve essere considerato refactoring e cosa cambia comportamento. Se non è chiaro, il primo finding può essere proprio la mancanza di separazione tra modifiche funzionali e modifiche di sicurezza.
Decisione prima del merge
Blocca il merge se la review trova access control incompleto, segreti esposti, query non filtrate, service key nel client, test di sicurezza rimossi, dipendenze sospette, debug in produzione, CORS permissivo senza motivo, error handling che espone dati o pipeline indebolita.
Puoi pianificare dopo il merge solo miglioramenti con rischio residuo basso e owner chiaro: documentazione, refactoring non urgente, aumento progressivo di test, riduzione di duplicazione, miglioramento naming. Le vulnerabilità che espongono dati, ruoli, pagamenti, cloud o deploy vanno corrette prima.
La decisione deve produrre evidenze: cosa è stato revisionato, quali finding sono stati corretti, quali test negativi sono stati aggiunti, quali rischi restano e chi li possiede.
Checklist per review di codice AI-generated
- Classifica file e aree toccate dal diff.
- Separa feature, refactor, test, dipendenze e configurazioni.
- Verifica auth, ruoli, tenant, middleware e controlli server-side.
- Leggi query, migration, policy e access layer.
- Controlla business logic, stati, idempotenza e casi fuori sequenza.
- Verifica input validation, output encoding, upload ed error handling.
- Cerca segreti, log verbosi, file .env, connection string e token.
- Rivedi dipendenze, lockfile, script e package nuovi.
- Controlla CI/CD, CORS, headers, Dockerfile, env, IaC e deploy.
- Pretendi test negativi per ogni area sensibile.
FAQ
- Se SAST e test sono verdi, serve ancora una Code Review?
- Sì. Scanner e test intercettano pattern e percorsi previsti, ma non sempre business logic, autorizzazioni, trust boundary, workflow e impatto del diff sul prodotto.
- Cosa guarda un reviewer umano che l’AI non vede?
- Il contesto applicativo: chi può fare cosa, quali dati sono sensibili, quali confini non vanno superati, quali assunzioni di business devono restare vere e quale rischio arriva in produzione.
- Quali PR AI sono più rischiose?
- Quelle che toccano auth, ruoli, API, database, segreti, dipendenze, CI/CD, cloud, pagamenti, upload, export, logging o configurazioni di deploy.
- La Code Review sostituisce il WAPT?
- No. La Code Review trova problemi nel codice e nella logica. Il WAPT verifica il comportamento reale dall’esterno. Su app esposte, spesso servono entrambi.
- Quando serve il Software Assurance Lifecycle?
- Quando l’AI coding viene usato stabilmente dal team e serve rendere ripetibili review, test, policy, gate e controlli su ogni release.
- Posso far revisionare solo una feature?
- Sì, se il perimetro è chiaro: PR, modulo, flusso, route o componente. Per feature che toccano dati e ruoli, serve includere anche test, configurazioni e dipendenze collegate.
Vuoi un codice sicuro e conforme?
Affidati a ISGroup per:
- Code review professionale di terza parte
- Metodologie e tecnologie avanzate di analisi
- Integrazione di sicurezza e qualità nello sviluppo
Non perderti il meglio della cybersecurity.
Ogni settimana, analisi esperte, attacchi reali e soluzioni concrete: tutto in un’unica newsletter.
Iscriviti alla newsletter Cyber WeeklyFonti e riferimenti utili
- OWASP Code Review Guide: https://owasp.org/www-project-code-review-guide/
- OWASP ASVS: https://owasp.org/www-project-application-security-verification-standard/
- OWASP Top 10 2021: https://owasp.org/Top10/2021/
- OWASP Broken Access Control: https://owasp.org/Top10/en/A01_2021-Broken_Access_Control/
- OWASP Authorization Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html
- OWASP Secrets Management Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
- OWASP SAMM: https://owasp.org/www-project-samm/

