Sviluppare un software che sia, già di per sé, orientato alla sicurezza non è solo un’attitudine che dovrebbe essere assimilata per via degli obblighi di legge, ma dovrebbe divenire la normalità tra gli sviluppatori in modo tale da fornire agli utenti delle tutele maggiori circa la protezione dei loro dati. È dunque utile analizzare le varie fasi che compongono il ciclo di vita dello sviluppo di software sicuro indicando anche delle possibili tecnologie che potranno essere gli strumenti nelle mani dei programmatori per la creazione di applicativi che implementano la sicurezza by design.
Indice degli argomenti
Sviluppo di software sicuro: l’importanza del by design
Facciamo un esempio. Consideriamo di dover costruire una casa e di dover scegliere tra due opzioni: costruire la casa seguendo le norme antisismiche fin da subito, oppure costruire la casa senza alcuna metodologia e solamente poi intervenire per renderla a norma.
Nella seconda casistica, per via dei lavori strutturali già effettuati, ci si potrebbe trovare in una situazione in cui potrebbe essere difficile, se non addirittura impossibile, omologarsi a quelle che sarebbero le normative in materia e non si raggiungerebbe, dunque, un’elevata efficacia nella protezione dello stabile da parte dei fenomeni sismici mettendo così a rischio tutte le persone che vi vivono dentro. L’abitabilità, la bellezza e la fruibilità dell’immobile, inoltre, potrebbero essere compromesse.
Alla stregua dell’esempio del problema edilizio appena descritto, vi sono importanti differenze nello sviluppare un software che già durante la progettazione strizza l’occhio ai requisiti di sicurezza rispetto a un altro che solamente in un secondo momento viene dotato di meccanismi di sicurezza. Come una casa, infatti, anche un programma ha un proprio scheletro portante che nel caso non fosse affidabile e robusto rischierebbe di collassare su stesso portando con sé anche tutti quegli elementi secondari a esso collegati.
In uno scenario come quello odierno, in cui la pandemia, per alcuni versi, ha forzato sia le organizzazioni pubbliche che quelle private a investire nella digitalizzazione, gli attaccanti sparsi per il mondo hanno avuto un aumento esponenziale delle superfici di attacco.
Come facilmente intuibile, infatti, nel 2020 vi è stato un incremento di quelli che sono stati gli incidenti e le violazioni informatiche. Emerge infatti dal Rapporto CLUSIT del 2021 un aumento del 12% per quanto riguarda l’occorrenza di attacchi informatici a livello globale. Di questi attacchi ben il 56% è stato classificato come avente un impatto di livello “alto” e/o “critico” mentre il 44% è stato classificato come gravità “media”.
In particolare, poi, interessante è il dato riguardante il fatto che nell’ultimo anno vi sia stata una crescita degli attacchi che sono stati portati efficacemente a compimento tramite lo sfruttamento di vulnerabilità note, rispetto invece agli anni passati in cui il trend era in calo.
Ferma restando la necessità di rispettare le norme di legge che impongono – direttamente o indirettamente – principi di progettazione sicura, alla luce di questi dati e del fatto che vi sarà sempre una maggior più digitalizzazione della società, risulta ancor più importante valutare e approcciarsi al mondo delle metodologie dello sviluppo di software sicuro in modo tale da progettare e rilasciare applicativi che rispondano alle esigenze di mercato in termini di sicurezza e che siano in grado di fronteggiare le minacce che ad oggi sono presenti online.
Le fasi del ciclo di vita dello sviluppo di software sicuro
Un normale ciclo di sviluppo del software contempla principalmente l’analisi, l’implementazione e il soddisfacimento dei requisiti funzionali che gli stakeholder hanno formulato e la relativa manutenzione dell’applicativo così realizzato. Il mero fatto di ignorare aspetti di sicurezza in questa metodologia comporta la possibilità di non rilevare eventuali vulnerabilità che vengono poi mantenute nel programma finale, il quale verrà rilasciato sul mercato.
L’obiettivo delle metodologie di sviluppo di software sicuro è quello di integrare nel classico ciclo di vita di sviluppo del software delle attività di verifica e rilevazione di possibili criticità dal punto di vista della sicurezza andando a inserire, dunque, anche la contemplazione non solo di requisiti funzionali bensì anche di sicurezza.
L’analisi dei requisiti di sicurezza, infatti, permette – tra le varie opportunità – la modellazione delle possibili minacce che potrebbero essere mosse all’applicativo in modo tale da agire preventivamente e adottare, fin dalle primissime fasi di progettazione, delle contromisure necessarie per impedire o quantomeno tentare di impedire che tali attacchi vadano a buon fine.
Di seguito andiamo a illustrare le sei principali fasi di un tradizionale ciclo di vita di sviluppo di software sicuro. Per ognuna di queste fasi riportiamo prima il nominativo della fase secondo il ciclo di sviluppo classico e poi il nominato (in inglese) della fase secondo il ciclo di sviluppo di software sicuro:
- Analisi dei requisiti e risk assessment.
- Analisi dei requisiti. La prima attività è quella di raccolta dei requisiti il software dovrà soddisfare e che sono stabiliti dagli stakeholder;
- Analisi del rischio. Una volta raccolti i requisiti, è necessario effettuare un’analisi per identificare, valutare e misurare la probabilità e la gravità dei rischi relativi alla sicurezza del software al fine di eliminarli o minimizzarli;
- Specifica dei requisiti. Infine, è necessario tradurre i requisiti e i relativi rischi in delle specifiche formali utilizzando un linguaggio di specifica software dotato anche delle apposite estensioni necessarie per rappresentare gli attacchi e i requisiti di sicurezza.
- Progettazione e threat modeling.
- Definizione della struttura. Sulla base delle specifiche formali si individua la struttura più adatta per la realizzazione del software;
- Definizione dell’architettura. Viene definita l’architettura funzionale e quella di sicurezza del software, in particolare: si documentano e modellano i meccanismi di sicurezza, gli elementi che delimitano la superfice d’attacco e le minacce;
- Produzione del “Concept di Progetto”. Prendendo in presto questo termine dal mondo dell’architettura, fine ultimo di questa fase è produrre tutta la documentazione concernente l’architettura del software completa di tutte le componenti.
- Implementazione e static analysis.
- Scrittura del codice. Sulla base delle disposizioni del Concept di Progetto, si scriverà il codice sorgente del software;
- Analisi del codice. Dopo aver scritto il codice si procede a effettuare delle analisi per verificare che il codice sia sintatticamente e semanticamente corretto;
- Test statici del codice. Vengono effettuati i primi test di sicurezza analizzando il codice sorgente per verificare l’assenza di falle e/o difetti di sicurezza.
- Verifica e dynamic analysis.
- Test funzionali. Il software viene eseguito e si verifica che esso rispetti le specifiche formali che catturano i requisiti funzionali;
- Test di sicurezza. Ci si accerta che i meccanismi e le contromisure di sicurezza fin qui implementate funzionino come da specifiche del Concept di Progetto;
- Correzioni preventive. In questa fase è possibile apportare delle correzioni al codice volte a eliminare o mitigare, in via preventiva, nuove vulnerabilità che non erano state precedentemente ravvisate.
- Validazione e final review secure.
- Controllo di sicurezza finale. Viene effettuato un ultimo test per accertarsi che tutte le vulnerabilità, fin qui ravvisate, siano state gestite;
- Incident Response Plan. Creare la documentazione contenente le istruzioni per rispondere e limitare gli effetti di un incidente di sicurezza;
- Rilascio. Al completamento positivo di queste attività si potrà procedere al rilascio del software
- Supporto e security monitoring.
- Manutenzione e assistenza. Bisogna fornire supporto per effettuare, in caso di necessità, attività di manutenzione per quanto riguarda aspetti funzionali o di sicurezza del software;
- Aggiornamento e patching. È necessario mantenere aggiornato il software, e le eventuali componenti esterne in base, ai più recenti progressi tecnologici del settore;
- Security assessment. Periodicamente dovrebbe essere svolto un controllo di sicurezza volto ad accertare la continua efficacia dei meccanismi di sicurezza nei confronti di eventuali nuove minacce.
Tecnologie esistenti per implementare tale modello di sviluppo
Per ognuna di queste fasi, a disposizione degli sviluppatori vi sono diversi strumenti per poter integrare la modellazione e la gestione delle minacce.
Fase di analisi dei requisiti e risk assessment
Nella fase di analisi dei requisiti e risk assessment è necessario carpire e rappresentare correttamente i requisiti espressi dagli stakeholder in modo tale da poterli poi tradurre in corrispettive specifiche formali che saranno poi analizzate e implementate dai programmatori.
In tale fase, lo strumento chiave degli sviluppatori è l’adozione di un linguaggio di specifica formale il quale permette, a differenza delle specifiche espresse mediante linguaggio naturale, di:
- far emergere la logica di funzionamento del software;
- dimostrare formalmente la correttezza del programma;
- generare casi di test attraverso cui validare e verificare l’applicativo.
Esempi famosi di linguaggi di specifica formale sono UML e AsmL. Per quanto riguarda la modellazione dei requisiti di sicurezza, di tali linguaggi esistono diverse estensioni quali UMLsec, SecureUML e AsmLSec che integrano nei linguaggi base delle funzioni per poter, a titolo esemplificativo: rappresentare requisiti di sicurezza sottoforma di vincoli che devono essere soddisfatti, definire delle politiche di controllo degli accessi e modellare le minacce e possibili scenari di attacco. Open Source Requirements Management Tool (OSRMT) e rmtoo sono due tool open source utilizzabili per la presenta fase.
Fase di progettazione e threat modeling
Nella fase di progettazione e threat modeling bisogna prendere le decisioni architetturali sulla base delle specifiche formali che si hanno a disposizione. Bisognerà, infatti, effettuare un’attività di ricerca e di consultazione per stabilire quali siano le migliori soluzioni tecnologiche disponibili che meglio si adattano al progetto da realizzare.
In genere, i linguaggi di specifica formale – come quelli visti poc’anzi – possono anche essere impiegati per la fase di progettazione.
Comunque, in questa fase bisognerebbe adottare un linguaggio di design sicuro che permetta di gestire correttamente la fase di threat modeling, quindi di rappresentazione delle minacce, delle superfici d’attacco e dei possibili pattern d’attacco, andando anche a definire, di conseguenza, le contromisure necessarie. Due tool open source utilizzabili per la realizzazione di questa fase sono Coras e SeaMonster – Security Modeling Software.
Fase di implementazione e static analysis
Nella fase di implementazione e static analysis si prenderà in consegna il Concept di Progetto e i programmatori dovranno sviluppatore l’applicativo seguendo le varie specifiche formali.
Una volta terminata la fase di scrittura del codice vi dovrà essere una fase di analisi statica del codice per verificarne la correttezza dal punto di vista sintattico e semantico in modo tale da ravvisare dei primi bug che potrebbero portare a malfunzionamenti e/o vulnerabilità sfruttabili da un attaccante.
Per questa fase vi sono diversi tool impiegabili per l’attività di controllo, di seguito alcuni esempi sempre open source: Brakeman, Dependency Check e SpotBugs.
Fase di verifica e dynamic analysis
Nella fase di verifica e dynamic analysis si effettuano dei test funzionali e di sicurezza dinamici per controllare che il programma si comporti e agisca “come da specifiche”.
In questa fase, sostanzialmente, si dovranno effettuare dei penetration test nei confronti del proprio stesso programma per stabilire quali sono le superfici d’attacco, quale impatto potrebbero avere determinati attacchi e quali potrebbero essere le vulnerabilità sfruttabili per danneggiare il sistema in modo tale da attuare delle correzioni preventive.
Esistono diversi tool che permettono di fare, tra le altre, penetration testing, dynamic application security testing (DAST) e runtime application security testing (RAST). Di seguito alcuni tool open source disponibili per effettuare tali attività: BeEF, OWASP Zed Attak Proxy (ZAP) e Samurai Web Testing Framework.
Fase di validazione e final review secure
Nella fase di validazione e final review secure, sostanzialmente, quello che verrà fatto e controllare che tutti i requisiti di sicurezza (e corrispettive specifiche) siano stati soddisfatti efficacemente dall’applicativo e, nel caso positivo, renderlo disponibile.
Per svolgere tale attività si possono utilizzare i medesimi tool citati nel paragrafo precedente. In aggiunta, se del caso, si possono adottare dei software release tool quali, a titolo esemplificativo, Armor Complete (non open source) che mette a disposizione, tra i vari, un servizio di hosting con diverse funzionalità di sicurezza integrabili quali sistemi di logging, intrusion dection/prevention system (IDS/IPS) e web application firewall.
Fase di supporto e security monitoring
Nella fase di supporto e security monitoring bisogna intraprendere tutte quelle attività di assistenza post-rilascio e bisogna continuamente mantenere aggiornato l’applicativo nei suoi vari componenti interni ed esterni (quali ad esempio le librerie utilizzate) per far sì che sia al passo con le recenti scoperte in termini di tecnologie/metodologie di sicurezza e nuove vulnerabilità note.
In questa fase possono essere impiegati dei software response tool per il miglioramento della gestione degli incidenti informatici. In questa tipologia di tool è raro trovarne di open source.
Di seguito, sono comunque segnalati alcuni sviluppati da importanti società e software house: CloudFlare, Cloud Access Security Broker (CASB), FortiGate NGFW e Sophos Next-Gen Firewall.
Conclusioni
Come per costruire in modo sicuro una casa, allo stesso modo per sviluppare un software che sia sicuro e che tuteli i propri utilizzatori è necessario adottare la corretta metodologia e gli strumenti corretti.
Sviluppare degli applicativi che sono stati realizzati anche per resistere a fenomeni avversi come tentativi di attacchi e sfruttamento di vulnerabilità è una delle possibili soluzioni per fronteggiare i pericoli e le minacce del mondo dell’informatica che, purtroppo, cresceranno di pari passi con la sempre maggior presenza e pervasività della tecnologia digitale nelle nostre vite.
In ultima analisi, si ricorda al lettore come questa metodologia, promossa da agenzie ed enti governativi quali AgID e l’ENISA, abbia un valore generalista e applicabile nella maggior parte dei contesti quotidiani, mentre per casi più specifici è possibile ricorrere a linee guida più dettagliate come, ad esempio, quelle rilasciate dall’autorità garante francese per la protezione dei dati (Commission Nationale de l’Informatique et des Libertés – CNIL) sulla piattaforma GitHub denominate “Guide RGPD du développeur”, o anche quelle rilasciate dall’autorità garante norvegese denominate “Software development with Data Protection by Design and by Default”.
DOCUMENTAZIONE DI RIFERIMENTO
- ISO/IEC 12207:2008 “Software life cycle processes”.
- ENISA “Privacy and Data Protection by Design – from policy to engineering” 12/2014.
- Ann Cavoukian “Privacy by Design – The 7 Foundational Principles”, Information & Privacy Commissioner, Ontario, Canada, 01/2011.
- ISO/IEC 29151:2017 “Code of practice for personally identifiable information protection”.
- MITRE Privacy Engineering Framework, MITRE Privacy Community of Practice (CoP) 07/2014.
- AgID “Linee guida per l’adozione di un ciclo di sviluppo di software sicuro” 12/2020.