7 falle di sicurezza comuni nel codice generato dall'IA (e come riconoscerle in 10 minuti)
Audit veloce senza essere esperti: 7 scorciatoie pericolose tipiche negli script da ChatGPT/Claude e come scovarle in pochi minuti.
Nel mio approfondimento sui rischi del vibe coding, ho analizzato il paradosso principale del software generato dai modelli linguistici: un codice che “funziona” al primo avvio non è automaticamente un codice sicuro. L’IA può privilegiare la rapidità e l’assenza di errori immediati, ricorrendo a scorciatoie che possono esporre computer o account a rischi concreti — non perché «sappia» di essere sicura, ma perché il prompt tipico chiede soprattutto che lo script giri.
La domanda che molti utenti non sviluppatori si pongono è comprensibile: come posso verificare l’affidabilità di uno script se non conosco i dettagli della sintassi di programmazione?
La risposta è confortante. Secondo la mia esperienza diretta nell’analisi di centinaia di prompt e script generati da ChatGPT, Claude e Cursor, ricorrono spesso gli stessi pattern (non in ogni output, ma abbastanza da renderli cercabili). Questi errori lasciano “impronte visive” precise all’interno del testo.
Non è necessario imparare a programmare da zero per intercettarli. È sufficiente aprire il file con un qualsiasi editor di testo (come VS Code o il semplice Blocco Note), premere Ctrl + F su Windows (o Cmd + F su Mac) e cercare le 7 stringhe sentinella descritte in questa guida. L’intera verifica richiede meno di 10 minuti.
1. Il disastro delle credenziali in chiaro (Hardcoding)
🔍 Cosa cercare con Ctrl+F: password =, api_key =, token =, secret = seguiti da testo racchiuso tra virgolette.
Quando chiedi all’assistente IA di interagire con un’API web o un servizio esterno, una scorciatoia tipica (non obbligatoria) è mettere la chiave di autenticazione direttamente nel corpo del file.
# Esempio tipico di hardcoding (da evitare)
TWILIO_TOKEN = "xyz_123456789_finto_token_segreto"
OPENAI_API_KEY = "sk-proj-abc1234567890abcdef"
- Perché è un rischio: Se condividi lo script su una chat, lo invii a un collega o carichi il progetto su GitHub per chiedere supporto, esponi all’istante le tue credenziali di accesso al pubblico o a scraper automatici.
- Come correggerlo nel prompt: Chiedi all’IA: “Modifica il codice per caricare le credenziali tramite la libreria
python-dotenvleggendole da un file.envseparato, oppure direttamente dalle variabili d’ambiente (os.environ). Crea anche un file.env.exampleprivo di segreti reali.”
2. Esecuzione cieca di comandi di sistema (shell=True)
🔍 Cosa cercare con Ctrl+F: shell=True, os.system(
Se chiedi all’IA di compiere operazioni sul sistema operativo (ad esempio zippare cartelle, interrogare la rete o avviare processi esterni), può usare il modulo subprocess con shell=True oppure os.system() — scorciatoie comuni in esempi da forum, non una scelta «obbligatoria» del modello.
# Esempio rischioso tipico (da evitare)
import subprocess
indirizzo_utente = input("Inserisci l'IP da verificare: ")
subprocess.run(f"ping {indirizzo_utente}", shell=True)
- Perché è un rischio: L’opzione
shell=Truepassa la stringa grezza all’interprete di comandi del sistema operativo. Se un input contiene caratteri speciali (come&& rm -rfsu Linux/Mac o& delsu Windows), il terminale eseguirà il comando aggiuntivo con gli stessi privilegi dell’utente. - Come correggerlo nel prompt: Chiedi all’IA: “Non usare
shell=Truee non usareos.system. Riscrivi la chiamata asubprocess.runpassando gli argomenti come lista di stringhe (['ping', indirizzo]), oppure usa librerie native Python per questa operazione.” - Approfondimento: la differenza tra stringa e lista vista in pratica, i parametri
check,timeoutecwd, i dettagli di Windows e uno script che trovashell=Truenei tuoi file sono nella guida ai pattern sicuri pershell=Trueesubprocessin Python.
3. Disattivazione della sicurezza di rete (verify=False)
🔍 Cosa cercare con Ctrl+F: verify=False, check_hostname=False
Quando uno script effettua richieste web su siti con certificati locali non configurati o connessioni particolari, la libreria requests può generare un errore SSL. Per far «funzionare» lo script senza intoppi, l’IA può disabilitare la convalida dei certificati — a volte è una scorciatoia di debug, non una best practice.
# Esempio tipico (da evitare)
import requests
risposta = requests.get("https://api.servizio.com/dati", verify=False)
- Perché è un rischio: Disattivare la verifica dei certificati espone il traffico a vulnerabilità Man-in-the-Middle (MitM). Chiunque si trovi sulla stessa rete Wi-Fi (ad esempio in uno spazio condiviso o in un locale pubblico) può intercettare, leggere o alterare i dati in transito.
- Come correggerlo: Rimuovi
verify=False. Se l’interprete Python restituisce errori di convalida SSL (frequente soprattutto al primo avvio su computer Apple), risolvi la configurazione a monte installando i certificati corretti, come spiegato nella guida completa all’installazione di Python su macOS.
4. Errori silenziati che mascherano i guasti (except: pass)
🔍 Cosa cercare con Ctrl+F: except Exception: pass, except: seguito solo da pass
Si tratta di un classico pattern di tolleranza artificiosa: per evitare messaggi di errore «brutti» in output, l’IA può racchiudere l’operazione in un blocco che sopprime qualsiasi segnalazione — utile in demo, rischioso in produzione.
# Esempio tipico (da evitare)
try:
salva_file_crittografato(dati_sensibili)
except Exception:
pass # Se il salvataggio fallisce, lo script continua in silenzio
- Perché è un rischio: Se il programma non riesce a salvare i dati, fallisce l’autenticazione o perde la connessione, continuerà a procedere senza avvisarti. Penserai che l’operazione sia andata a buon fine quando in realtà i dati sono andati persi o non sono stati protetti.
- Come correggerlo nel prompt: Chiedi all’IA: “Non utilizzare blocchi try/except generici con
pass. Cattura solo le eccezioni specifiche attese, stampa sempre il messaggio di errore a schermo e interrompi l’esecuzione in sicurezza in caso di fallimento critico.”
5. Esposizione dell’applicazione all’intera rete locale (0.0.0.0)
🔍 Cosa cercare con Ctrl+F: 0.0.0.0
Se chiedi all’IA di generare una piccola interfaccia web o un server locale (utilizzando framework come Flask, FastAPI o Streamlit), il modello può impostare l’host su 0.0.0.0 (spesso copiato da tutorial «accessibile in LAN»).
# Esempio rischioso su reti pubbliche (da evitare)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
- Perché è un rischio: L’indirizzo
0.0.0.0istruisce il server ad accettare connessioni in entrata da qualunque interfaccia di rete, inclusi tutti i dispositivi collegati alla stessa rete Wi-Fi locale. - Come correggerlo: Sostituisci
0.0.0.0con127.0.0.1. In questo modo il servizio sarà raggiungibile esclusivamente dal tuo computer locale.
ℹ️ Nota operativa — Modalità Debug Oltre all’indirizzo IP, fai attenzione alla presenza di
debug=True. In fase di sviluppo locale assistito è comodo, ma in ambienti con dati sensibili la modalità debug può esporre una console interattiva nel browser che permette l’esecuzione di comandi arbitrari.
6. Deserializzazione insicura di dati (eval e pickle.load)
🔍 Cosa cercare con Ctrl+F: eval(, exec(, pickle.load(
Quando uno script deve salvare o rileggere strutture di dati dal disco, l’IA può proporre funzioni come eval() o il modulo pickle — comode e veloci, ma pericolose con input non fidati.
# Esempio tipico (da evitare)
import pickle
with open("dati_utente.dat", "rb") as f:
dati = pickle.load(f) # Se il file è compromesso, esegue codice malevolo
- Perché è un rischio: La funzione
eval()esegue qualsiasi stringa passata come codice sorgente. Il modulopickle, per sua stessa definizione nella documentazione ufficiale, non è sicuro contro dati manomessi: deserializzare un file pickle proveniente da fonti non fidate equivale a eseguire un file eseguibile arbitrario. - Come correggerlo nel prompt: Chiedi all’IA: “Non utilizzare
eval(),exec()opickle. Riscrivi il salvataggio e la lettura dei dati utilizzando il formato standardjson(json.dump/json.load) o SQLite parametrizzato.” - Approfondimento: la differenza vista in pratica, le alternative una per una (
ast.literal_eval,json,tomllib,configparser, validazione con dataclass o pydantic,yaml.safe_load), la firma HMAC quandopicklenon si può togliere e uno script che trovaeval,execepickle.loadnei tuoi file sono nella guida alle alternative sicure aevalepickleper dati e configurazione in Python.
7. Pacchetti allucinati e inventati nel comando di installazione
Questa criticità non si cerca all’interno del file di codice, ma tra le istruzioni di setup fornite dall’IA (i comandi del tipo pip install nome-libreria).
- Perché è un rischio: L’IA può allucinare il nome di un pacchetto ipotetico (es.
super-fast-pdf-cleaner). I criminali informatici monitorano questi suggerimenti frequenti e registrano pacchetti malevoli con quei nomi esatti su PyPI o npm, distribuendo malware a chi fa copia-incolla senza verificare. - Come correggerlo: Prima di digitare
pip installper una libreria che non hai mai sentito nominare, cercala manualmente su pypi.org. Verifica che il progetto esista da tempo, conti un numero considerevole di download e disponga di una pagina GitHub con manutenzione attiva.
Tabella di sintesi per l’Audit Veloce in 10 Minuti
Tieni questa matrice a portata di mano ogni volta che l’IA ti fornisce un nuovo script da eseguire:
| Stringa Sentinella | Livello Rischio | Problema Rilevato | Cosa fare / Come correggere |
|---|---|---|---|
password =, api_key = |
Critico | Chiavi di autenticazione e token salvati in chiaro nel sorgente | Spostare i valori in un file .env ed escluderlo dal controllo di versione. |
shell=True, os.system( |
Critico | Esecuzione insicura di comandi di sistema (Command Injection) | Passare argomenti come lista a subprocess.run o usare librerie native. |
verify=False |
Critico | Disattivazione della verifica crittografica dei certificati SSL/TLS | Rimuovere il flag e configurare correttamente i certificati di sistema. |
except Exception: pass |
Medio | Soppressione cieca degli errori e fallimenti silenziosi | Catturare eccezioni specifiche e stampare il messaggio di errore nel log. |
0.0.0.0 |
Situazionale | Server locale esposto a tutti i dispositivi della rete Wi-Fi | Sostituire con 127.0.0.1 per consentire l'accesso solo dal computer locale. |
eval(, pickle.load( |
Critico | Esecuzione arbitraria di codice durante la lettura dei dati | Sostituire con formati sicuri e standardizzati come json. |
pip install [pacchetto] |
Critico | Rischio di dipendenze allucinate o squatting malevolo | Verificare sempre l'autorevolezza e lo storico del pacchetto su PyPI prima dell'installazione. |
Domande Frequenti (FAQ)
È sufficiente questa checklist di 10 minuti per dire che un programma è «sicuro al 100%»?
No. Questa checklist visiva aiuta a intercettare molte delle scorciatoie grossolane più ricorrenti (nei miei test) negli script generati dagli assistenti IA. Per script personali, automazioni d’ufficio e strumenti locali è un filtro utile. Per software che gestisce pagamenti, dati sanitari o piattaforme aperte al pubblico serve una security review strutturata (SAST e revisione umana).
Perché l’IA può proporre shell=True o verify=False anche se sono sconsigliati?
I modelli sono addestrati su enormi moli di codice pubblico: forum, snippet di debug e prototipi datati. Quando il prompt chiede soprattutto «falla funzionare», l’IA può scegliere la scorciatoia che evita l’errore immediato — non perché «sappia» che è sicura.
Posso usare estensioni per VS Code che automatizzano questo controllo?
Sì. Strumenti e linters come bandit (specifico per la sicurezza in Python), Flake8 e semgrep possono essere integrati nel tuo editor di sviluppo per evidenziare automaticamente pattern rischiosi in tempo reale mentre esamini il codice.
Cosa succede se dimentico debug=True in un’applicazione web generata con Flask?
In ambiente locale protetto il rischio è minimo; tuttavia, se l’applicazione viene eseguita su una rete condivisa o resa accessibile dall’esterno con 0.0.0.0, la schermata di errore interattiva del debugger di Flask consente a chiunque di eseguire codice Python arbitrario direttamente dal browser sul tuo computer.
Come cerco queste falle in un file senza strumenti avanzati?
Apri il file nel tuo editor e usa la ricerca testuale (Ctrl + F su Windows/Linux, Cmd + F su macOS) sulle stringhe tipiche: password =, api_key, shell=True, verify=False, except:, 0.0.0.0, eval(, pickle.load. Se una riga compare, fermati e chiediti se è voluta e se c’è un’alternativa più sicura — è esattamente il filtro da 10 minuti di questa guida.
Prossimi passi consigliati
- Consulta l’articolo introduttivo sul vibe coding e l’affidamento cieco all’IA per comprendere a fondo le dinamiche di generazione del codice.
- Prima di generare un modulo critico, usa la libreria di prompt misurabili (SQL, env, TLS, shell, CORS) invece di «scrivi codice sicuro».
- Per scovare
exceptsilenziosi e altri indizi strutturali in sola lettura: scanner AST stdlib. - Metti alla prova il tuo sito prima della pubblicazione con la guida su come fare un audit di sicurezza gratuito, passo per passo.
- Isola gli script locali: se Python manca, usa la guida all’installazione di Python su Windows, la guida all’installazione di Python su macOS o la guida all’installazione di Python su Linux; poi crea un ambiente dedicato con Ambienti virtuali Python (venv) in 5 minuti.