Approfondimenti e Trend sull'Intelligenza Artificiale

Find in Files: stringhe spia per revisionare codice generato

10 min di lettura
Cassetto di legno di un vecchio schedario da biblioteca aperto e pieno di schede, tra decine di cassetti chiusi con le targhette
Windows macOS Linux
Foto: Tima Miroshnichenko · Pexels · Licenza Pexels

Sei ricerche regex da incollare in Find in Files di VS Code o Cursor per trovare in tutto il progetto le righe rischiose del codice scritto dall’IA.

Il secondo passaggio del protocollo di revisione del codice generato dall’IA è una ricerca nell’editor sulle stringhe spia: verify=False, shell=True, 0.0.0.0, eval( e simili. Qui trovi le ricerche pronte da incollare e le impostazioni del pannello che decidono se vedi i tuoi file o migliaia di righe di librerie. Find in Files non giudica il codice: ti porta in un clic su ogni riga che merita di essere letta, file per file.

La risposta breve: apri la cartella del progetto in VS Code o Cursor, premi Ctrl+Shift+F (su macOS Cmd+Shift+F), attiva le espressioni regolari e incolla le sei ricerche di questa pagina una alla volta. Sul progetto di prova, con falle scritte apposta in un file Python e uno JavaScript, le sei ricerche hanno trovato 16 righe da controllare e nessuna riga dalle librerie installate.

ℹ️ Nota / Prerequisito operativo: ti serve VS Code o Cursor, con il progetto aperto come cartella (File → Apri cartella). Find in Files cerca solo nella cartella aperta: se apri un singolo file, la ricerca non vede il resto del progetto. Se preferisci il terminale o vuoi un comando da lanciare in automatico, la stessa idea è nello script greppabile per cercare le 7 falle in un repo.

Aprire la ricerca e attivare le espressioni regolari

Il pannello si apre con Ctrl+Shift+F su Windows e Linux, Cmd+Shift+F su macOS, oppure con l’icona della lente nella barra laterale. Cursor è basato su VS Code e ne eredita il pannello.

Nella casella di ricerca ci sono tre interruttori, in questo ordine:

  • Aa (Match Case): lascialo spento, così API_KEY e api_key vengono trovati entrambi.
  • ab (Match Whole Word): lascialo spento, le ricerche di questa pagina gestiscono già i confini delle parole.
  • .* (Use Regular Expression): accendilo. Senza, il pannello cerca il testo alla lettera e verify\s*=\s*False non trova nulla.

Sotto la casella, l’icona con i tre puntini (Toggle Search Details, Ctrl+Shift+J su Windows e Linux, Cmd+Shift+J su macOS) mostra due campi: files to include e files to exclude. Servono nella sezione sulle cartelle da escludere.

Pannello di ricerca di VS Code su Linux con l’interruttore delle espressioni regolari attivo, la prima ricerca incollata e i campi files to include e files to exclude visibili
Il pannello di ricerca con le espressioni regolari attive e i campi per includere ed escludere file: i risultati sono raggruppati per file. Screenshot: ai riparo

Le sei ricerche da incollare

Ogni riga è una ricerca completa: copiala nella casella, guarda i risultati, poi passa alla successiva. Il simbolo | significa «oppure», quindi ogni ricerca copre più stringhe dello stesso tipo.

verify\s*=\s*False|ssl\s*=\s*False|check_hostname\s*=\s*False|rejectUnauthorized:\s*false|NODE_TLS_REJECT_UNAUTHORIZED
shell\s*=\s*True|os\.system\(|child_process|execSync\(
(^|[^\w.])(eval|exec)\(|pickle\.loads?\(|yaml\.load\(|innerHTML\s*=|dangerouslySetInnerHTML
(execute|query)\(\s*f["']|(SELECT|INSERT|UPDATE|DELETE)\b.*["']\s*\+
0\.0\.0\.0|debug\s*=\s*True|origin:\s*["']\*["']
(api_?key|secret|token|password)\w*\s*[=:]\s*["'][^"']{8,}

Cosa cerca ogni riga:

  • Riga 1, rete senza verifica dei certificati: verify=False e ssl=False in Python, rejectUnauthorized: false e la variabile NODE_TLS_REJECT_UNAUTHORIZED in Node.js.
  • Riga 2, comandi di sistema: shell=True e os.system( in Python, il modulo child_process ed execSync( in Node.js.
  • Riga 3, codice o HTML costruito dai dati: eval( ed exec( non preceduti da un punto o da una lettera (così ast.literal_eval( non compare), pickle.load, yaml.load(, innerHTML = e dangerouslySetInnerHTML di React.
  • Riga 4, query SQL composte a mano: una query in f-string dentro execute( o query(, oppure una riga con SELECT, INSERT, UPDATE o DELETE seguita da una stringa chiusa e da un +.
  • Riga 5, app troppo aperta: 0.0.0.0, debug=True e origin: "*", cioè CORS aperto a qualsiasi sito.
  • Riga 6, credenziali scritte nel codice: un nome come api_key, secret, token o password, poi = o : e un testo tra virgolette di almeno 8 caratteri. DB_PASSWORD = os.environ.get(...) non compare, perché dopo l’uguale non ci sono virgolette.

💡 Consiglio pratico — Tieni le ricerche nel progetto: salva le sei righe in un file di testo nella cartella del progetto, per esempio stringhe-spia.txt, e copiale da lì. Il pannello ricorda anche le ricerche recenti: con il cursore nella casella, le frecce su e giù le richiamano.

Il risultato sul progetto di prova

VS Code esegue Find in Files con ripgrep, come spiega la sua documentazione sulla ricerca nei file. Ho quindi provato le sei ricerche con ripgrep 14.1.1, senza distinzione tra maiuscole e minuscole come nel pannello, su un progetto con due file scritti apposta: app/server.py e web/server.js. Nel progetto c’erano anche una query SQL scritta correttamente con il segnaposto ?, una chiamata ast.literal_eval, una password letta da una variabile d’ambiente e due librerie finte in .venv/ e node_modules/, entrambe elencate in .gitignore.

Risultato della riga 3:

./web/server.js:8:  document.getElementById("saluto").innerHTML = req.query.nome;
./web/server.js:9:  exec("ls " + req.query.dir);
./app/server.py:23:    return pickle.loads(dati)
./app/server.py:26:    return yaml.load(testo, Loader=yaml.Loader)
./app/server.py:29:    return eval(espr)

In totale le sei ricerche hanno segnalato 16 righe, tutte tra quelle scritte apposta. Nessun risultato per la query con ?, per literal_eval, per la password letta dall’ambiente e per i file in .venv/ e node_modules/. Nel pannello vedi le stesse righe raggruppate per file: un clic su una riga apre il file in quel punto. Ho poi ripetuto la riga 1 nel pannello Cerca di VS Code 1.143.1 su Debian 13, su una cartella di prova con un solo file Python: un risultato, la riga con verify=False, come nello screenshot più in alto.

Cartelle da includere ed escludere

Il campo files to exclude ha accanto un interruttore a forma di ingranaggio, Use Exclude Settings and Ignore Files. Quando è attivo, la ricerca salta i file elencati in .gitignore e quelli esclusi dalle impostazioni files.exclude e search.exclude. Per impostazione predefinita VS Code esclude già cartelle come node_modules.

La cartella .venv, invece, viene saltata solo se compare in .gitignore. Se non c’è, le ricerche ti mostrano anche il codice delle librerie installate, che non hai scritto tu. Due soluzioni:

  • aggiungi .venv/ al file .gitignore del progetto, che è comunque la scelta giusta;
  • scrivi nel campo files to exclude: .venv, venv, node_modules, dist, build.

Per limitare la ricerca ai file di codice, nel campo files to include scrivi *.py, *.js, *.ts. Separa i nomi con la virgola; nel pannello il prefisso **/ è implicito, quindi *.py vale per tutte le sottocartelle.

Nella prova, spegnendo il rispetto di .gitignore (rg --no-ignore), la riga 3 ha aggiunto node_modules/x/index.js:1:el.innerHTML = x, cioè una libreria di terzi. Se il pannello mostra centinaia di risultati da cartelle che non riconosci, l’interruttore a ingranaggio è spento.

Solo i file che l’IA ha appena cambiato

Se il progetto usa Git, nel campo files to include c’è un secondo interruttore: Search only in changed files, che limita la ricerca ai file con modifiche non ancora salvate in un commit. È il modo più rapido di revisionare una sessione con l’IA: fai un commit prima di chiederle modifiche, poi lanci le sei ricerche solo sui file che ha toccato. L’interruttore è descritto nella documentazione di VS Code ed è disattivato quando non ci sono modifiche.

Cosa la ricerca non trova

Le ricerche trovano testo, non capiscono il codice.

Due persone con metal detector e pala camminano su una spiaggia grigia all’alba, di spalle al mare
Come un metal detector: suona dove c’è metallo, ma cosa c’è sotto lo scopri solo scavando. E quello che non suona non è per forza assente. Foto: David Kanigan · Pexels

In un secondo file di prova le ricerche non hanno segnalato tre righe pericolose:

from pickle import loads
opzioni = {"shell": True}
query = "SELECT * FROM t WHERE n = %s" % nome

La prima importa loads da solo, quindi più avanti nel codice compare loads(dati) senza pickle.. La seconda passa shell come chiave di un dizionario. La terza compone la query con % invece che con + o con una f-string. Un pannello vuoto significa che quelle stringhe non compaiono, non che il codice è sicuro.

Il caso opposto sono i falsi positivi: 0.0.0.0 in un commento, eval( dentro un messaggio che spiega cosa non fare, innerHTML = con un testo fisso scritto da te. Ogni risultato va aperto e letto nel suo contesto prima di cambiare qualcosa.

⚠️ Attenzione — Non usare Replace All: il pannello ha anche un campo di sostituzione su tutti i file. Sostituire verify=False o shell=True in blocco può rompere il programma o spostare il problema altrove. Correggi una riga alla volta, seguendo la guida dedicata alla falla.

Errori tipici

  • Nessun risultato anche se le stringhe ci sono → l’interruttore .* è spento e il pannello cerca il testo alla lettera, barre rovesciate comprese → accendi Use Regular Expression e rilancia.
  • La casella di ricerca si colora di rosso e non compare nessun risultato → la riga è stata copiata solo in parte, per esempio senza l’ultima parentesi → ricopia la riga intera dal blocco sopra.
  • Centinaia di risultati da .venv o node_modules → l’interruttore a ingranaggio di files to exclude è spento, oppure .venv non è in .gitignore → riattiva l’interruttore e aggiungi le cartelle nel campo di esclusione.
  • La ricerca trova solo i file aperti → nel campo files to include è attivo l’interruttore Search Only in Open Editors → spegnilo.
  • I risultati arrivano solo da una sottocartella → hai avviato la ricerca da Find in Folder nel menu del tasto destro, o il campo files to include contiene un percorso → svuota il campo.

Domande Frequenti (FAQ)

Find in Files o script da terminale: quale conviene?

Find in Files è più comodo mentre lavori: un clic e sei sulla riga, con il codice intorno. Lo script greppabile conviene quando vuoi lanciare lo stesso controllo su più progetti, salvare l’elenco in un file o automatizzarlo prima di ogni consegna.

Funziona anche in Cursor o in altri editor basati su VS Code?

Cursor è basato su VS Code e ne eredita il pannello di ricerca, con le stesse scorciatoie predefinite. Negli altri editor derivati da VS Code la struttura è di solito la stessa; se un interruttore non c’è, cerca nella documentazione dell’editor la voce sulla ricerca nei file.

Posso chiedere all’IA di cercare queste stringhe al posto mio?

Puoi, ma una ricerca deterministica ti dà l’elenco completo delle righe che corrispondono, ogni volta uguale. Un assistente può saltare un file o riassumere. Usa l’IA dopo, per farti spiegare una riga trovata.

Devo cercare anche nei file .env?

I file .env sono il posto giusto per le chiavi, se sono elencati in .gitignore. Proprio per questo il pannello di solito li salta. Il controllo da fare è un altro: verifica che .env sia in .gitignore e che non sia mai finito in un commit.

Ogni quanto lanciare le sei ricerche?

Dopo ogni sessione in cui l’IA ha scritto o riscritto parti del progetto, e sempre prima di metterlo online. Con Search only in changed files il controllo richiede pochi minuti.

Dopo la ricerca

Apri ogni risultato, decidi se è un problema reale e correggilo con la guida giusta: per i comandi di sistema i pattern sicuri per shell=True e subprocess, per eval e pickle le alternative sicure per dati e configurazione, per origin: "*" la guida su CORS con l’asterisco nelle API. Il quadro completo delle falle è nelle 7 falle di sicurezza nel codice scritto dall’IA. Se vuoi che sia qualcun altro a passare il progetto riga per riga, è un lavoro che faccio anche su richiesta. Per i passaggi successivi della revisione, torna al protocollo per il codice generato dall’IA.

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
  • sicurezza,
  • vs code,
  • cursor,
  • regex,
  • vibe coding