Sicurezza di siti e app IA

7 falle di sicurezza comuni nel codice generato dall'IA (e come riconoscerle in 10 minuti)

10 min di lettura
Laptop scuro con codice verde luminoso sullo schermo, ambiente buio
Windows macOS Linux
Foto: Markus Spiske · Unsplash · Licenza Unsplash

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-dotenv leggendole da un file .env separato, oppure direttamente dalle variabili d’ambiente (os.environ). Crea anche un file .env.example privo 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=True passa la stringa grezza all’interprete di comandi del sistema operativo. Se un input contiene caratteri speciali (come && rm -rf su Linux/Mac o & del su Windows), il terminale eseguirà il comando aggiuntivo con gli stessi privilegi dell’utente.
  • Come correggerlo nel prompt: Chiedi all’IA: “Non usare shell=True e non usare os.system. Riscrivi la chiamata a subprocess.run passando 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, timeout e cwd, i dettagli di Windows e uno script che trova shell=True nei tuoi file sono nella guida ai pattern sicuri per shell=True e subprocess in 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.0 istruisce 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.0 con 127.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 modulo pickle, 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() o pickle. Riscrivi il salvataggio e la lettura dei dati utilizzando il formato standard json (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 quando pickle non si può togliere e uno script che trova eval, exec e pickle.load nei tuoi file sono nella guida alle alternative sicure a eval e pickle per 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 install per 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

Alex Lunalbi

Alex Lunalbi

Security & privacy

Dona su PayPal

Scrivo di sicurezza digitale pratica e codice IA. Su ai riparo ogni procedura è verificata su macchine reali.

Tag
  • intelligenza artificiale,
  • vibe coding,
  • python,
  • sicurezza,
  • audit