L'analisi statica del codice (SCA) è un metodo per controllare il codice sorgente del computer alla ricerca di bug, vulnerabilità di sicurezza e codice non ottimale senza eseguire il programma. Utilizza strumenti automatizzati per scansionare il codice ed eseguire analisi avanzate in tempo reale.
Nota anche come analisi del codice sorgente, l'analisi statica del codice identifica gli errori logici e le perdite di memoria prima dell'esecuzione delle applicazioni, riducendo i tempi di debug. Scansiona automaticamente errori di sintassi e vulnerabilità di sicurezza nascoste che gli umani potrebbero non notare. Contribuisce a far rispettare gli standard di codifica e a garantire la conformità normativa all’interno di team numerosi, accelerando in generale lo sviluppo.
L'analisi statica del codice, a differenza dell'analisi dinamica del codice, avviene prima dell'esecuzione del codice. L'analisi dinamica prevede l'esecuzione dell'applicazione e l'osservazione del suo comportamento. Al contrario, l’analisi statica tratta il codice sorgente come un set di dati strutturati, che analizza per individuare eventuali problemi prima ancora che l’applicazione venga compilata, pacchettizzata o distribuita. Questo approccio modella il comportamento del programma in base alla sua struttura. Entrambe le tecniche sono importanti per un approccio complessivo alla garanzia della qualità all’interno di un framework devops o devsecops.
Resta al passo con le tendenze più importanti e interessanti del settore relative ad AI, automazione, dati e oltre con la newsletter Think. Leggi l' Informativa sulla privacy IBM.
L’analisi statica del codice prevede tre fasi principali.
L'analizzatore legge il codice sorgente e lo scompone in token. Questi vengono passati a un parser che li valuta in base alle regole sintattiche di uno specifico linguaggio di programmazione e li riorganizza in un albero sintattico astratto (AST) gerarchico. L'AST mappa la struttura del software in un formato leggibile dalla macchina.
L’analizzatore costruisce un grafo del flusso di controllo (CFG) per mappare i percorsi di esecuzione, combinandolo con l’analisi del flusso dei dati per monitorare come cambiano i valori delle variabili dall’inizializzazione al loro utilizzo. È in questa fase che l’analizzatore può individuare errori come il codice morto (codice che non può mai essere eseguito).
Utilizzando l’AST e i modelli di flusso, lo strumento verifica il codice rispetto alle linee guida di codifica e alle euristiche. Questi controlli spaziano da semplici convenzioni di denominazione a verifiche di sicurezza più sofisticate, come la taint analysis, che traccia gli input dell’utente potenzialmente contaminati e che potrebbero portare a iniezioni SQL.
Agli albori dell’informatica, l’esecuzione del codice era costosa e gli sviluppatori non potevano permettersi di sprecare risorse di calcolo per il debugging. La verifica era interamente affidata all’intelligenza umana, attraverso revisioni del codice lente e manuali.
La creazione di Lint nel 1978 da parte di Stephen C. Johnson presso i Bell Labs segna l’inizio della moderna analisi statica del codice. Lint è stato sviluppato per il sistema operativo Unix ed è stato progettato per analizzare il codice sorgente e segnalare costrutti sospetti prima della compilazione.
Lint individuava il codice problematico da rimuovere senza modificare la logica del programma, consentendo di risparmiare preziose risorse di calcolo. Johnson chiamò Lint così in riferimento alla lanugine che si accumula nel filtro dell’asciugatrice, perché il suo strumento eliminava il codice problematico e indesiderato (la “lanugine”) senza modificare la logica (la struttura degli indumenti).
Con la crescita di Internet negli anni ’90 e 2000, è aumentata anche la necessità di mitigare le vulnerabilità di sicurezza. Sono emersi nuovi strumenti per rispondere a questa esigenza, insieme a forme di analisi più complesse che trasformavano il codice compilato in modelli matematici per tracciare come si propagavano le variabili. Sono emersi nuovi framework come lo static application security testing (SAST) per contrastare queste minacce, mentre metodi come il dynamic application security testing (DAST) hanno consentito di effettuare valutazioni durante l’esecuzione.
Sebbene matematicamente precise, queste tecniche soffrivano di alti tassi di falsi positivi a causa della loro scarsa capacità di comprendere il contesto. L'ascesa del machine learning e dei modelli linguistici di grandi dimensioni (LLM) negli anni 2020 ha dato il via a una nuova era dell’analisi del codice, in cui i modelli potevano essere addestrati su miliardi di righe di codice. Questo addestramento ha dato loro la capacità di dedurre l'intento dello sviluppatore e il contesto semantico.
Tradizionalmente, l’analisi statica del codice era un processo di controllo eseguito prima del rilascio, ma oggi viene effettuata durante tutto il ciclo di vita dello sviluppo software (SDLC). Questa filosofia "shift left" prevede lo spostamento dei test "verso sinistra", più vicino alla creazione del codice.
Oggi, strumenti di analisi del codice come SonarQube, ESLint e GitHub Advanced Security sono parte integrante del workflow degli sviluppatori. Funzionano all'interno di ambienti di sviluppo integrati (IDE) per segnalare gli errori in tempo reale durante la digitazione da parte dello sviluppatore. Fungono inoltre da checkpoint automatizzati all'interno delle pipeline di continuous integration e continuous deployment, o pipeline CI/CD.
I moderni assistenti alla codifica basati sul machine learning hanno reso possibile un'analisi decentralizzata del codice, rapida e in gran parte invisibile, consentendo agli sviluppatori di individuare gli errori in anticipo e migliorare la qualità del codice in tempo reale. IBM Bob, ad esempio, dispone di un workflow “Review” che viene eseguito in un pannello separato e cerca automaticamente code smell, segnalando le violazioni degli standard di codifica, che gli utenti possono poi ignorare oppure far risolvere automaticamente a Bob.
L'analisi può essere condotta anche in modo proattivo attraverso stimoli strategici. Ad esempio, invece di chiedere a un assistente di codifica di "trovare i bug", uno sviluppatore può chiedergli di esaminare i repository con obiettivi specifici in mente. Per una revisione dell'architettura, si può chiedere all'assistente di esaminare l'organizzazione delle directory, i punti di ingresso, le relazioni tra i componenti e l'intero stack tecnologico, generando una documentazione dettagliata. Un prompt che analizza la progettazione del database può individuare gli obiettivi di modernizzazione. Prompt specializzati possono esaminare la progettazione del database, analizzare le migrazioni ed effettuare una revisione completa del debito tecnico, con raccomandazioni su come risolvere i problemi nel modo più strategico.
Accelera la distribuzione del software con IBM® Bob, il tuo partner AI per uno sviluppo sicuro e consapevole degli intenti.
Sviluppa, implementa e gestisci le applicazioni AI più velocemente con strumenti pensati per le aziende.
Reinventa i sistemi legacy con la modernizzazione intelligente dell'AI.