Suggerimenti per la protezione di un ciclo di vita di sviluppo

Si applica a questa raccomandazione dell'elenco di controllo per la sicurezza di Azure Well-Architected Framework:

SE:02 Mantenere un ciclo di vita di sviluppo sicuro usando una catena di approvvigionamento software con protezione avanzata, per lo più automatizzata e controllabile. Incorporare una progettazione sicura usando la modellazione delle minacce per proteggersi dalle implementazioni di sicurezza non superate.

Guida correlata: Analisi delle minacce

Questa guida descrive le raccomandazioni per la protezione avanzata del codice, dell'ambiente di sviluppo e della supply chain del software applicando le procedure consigliate per la sicurezza in tutto il ciclo di sviluppo. Per comprendere queste linee guida, è necessario conoscere DevSecOps.

Diagramma del ciclo di sicurezza.

DevSecOps integra la sicurezza nei processi DevOps tramite:

  • Automazione dei test e della convalida della sicurezza.

  • Implementazione di strumenti come le pipeline di sicurezza per analizzare il codice e l'infrastruttura come codice (IaC) per individuare le vulnerabilità.

Al centro di un carico di lavoro è il codice dell'applicazione che implementa la logica di business. Il codice e il processo di sviluppo del codice devono essere privi di difetti di sicurezza per garantire riservatezza, integrità e disponibilità.

Non è sufficiente proteggere solo il piano dell'infrastruttura usando controlli sull'identità e sulla rete e altre misure. Evitare un'implementazione errata del codice o un blocco di codice compromesso per rafforzare il comportamento di sicurezza complessivo. Anche il piano di utilizzo, ovvero il codice dell'applicazione, deve essere sottoposto a protezione avanzata. Il processo di integrazione della sicurezza nel ciclo di vita dello sviluppo è essenzialmente un processo di protezione avanzata. Analogamente alla protezione avanzata delle risorse, anche lo sviluppo di codice è indipendente dal contesto. L'obiettivo è migliorare la sicurezza e non i requisiti funzionali dell'applicazione. Per informazioni relative alla protezione avanzata, vedere Raccomandazioni per la protezione avanzata delle risorse.

Definizioni

Termine Definizione
Security Development Lifecycle (SDL) Un set di procedure fornite da Microsoft che supporta i requisiti di sicurezza e conformità.
Ciclo di vita dello sviluppo software (SDLC) Un processo sistematico e multistage per lo sviluppo di sistemi software.

Strategie di progettazione chiave

Le misure di sicurezza devono essere integrate in più punti nel ciclo di vita di sviluppo software (SDLC) esistente per garantire:

  • Le scelte di progettazione non comportano lacune nella sicurezza.

  • Il codice e la configurazione dell'applicazione non creano vulnerabilità a causa di implementazioni sfruttabili e procedure di codifica non corretta.

  • Il software acquisito tramite la supply chain non introduce minacce per la sicurezza.

  • Il codice dell'applicazione, la compilazione e i processi di distribuzione non vengono manomessi.

  • Le vulnerabilità rivelate tramite eventi imprevisti vengono attenuate.

  • Le risorse inutilizzate vengono rimosse correttamente.

  • I requisiti di conformità non vengono compromessi o ridotti.

  • La registrazione di controllo viene implementata negli ambienti di sviluppo.

Le sezioni seguenti forniscono strategie di sicurezza per le fasi comunemente pratiche di SDLC.

Fase dei requisiti

L'obiettivo della fase dei requisiti è raccogliere e analizzare i requisiti funzionali e non funzionali per un'applicazione o una nuova funzionalità di un'applicazione. Questa fase è importante perché facilita la creazione di protezioni personalizzate in base agli obiettivi dell'applicazione. La protezione dei dati e dell'integrità dell'applicazione deve essere un requisito fondamentale per ogni fase del ciclo di vita dello sviluppo.

Si consideri ad esempio un'applicazione che deve supportare flussi utente critici che consentono all'utente di caricare e modificare i dati. Le scelte di progettazione della sicurezza devono coprire le garanzie per l'interazione dell'utente con l'applicazione, ad esempio l'autenticazione e l'autorizzazione dell'identità utente, consentendo solo le azioni consentite sui dati e impedendo l'inserimento di SQL. Analogamente, coprire i requisiti non funzionali, ad esempio disponibilità, scalabilità e gestibilità. Le scelte di sicurezza devono includere limiti di segmentazione, ingresso e uscita del firewall e altri problemi di sicurezza trasversali.

Tutte queste decisioni devono portare a una buona definizione del comportamento di sicurezza dell'applicazione. Documentare i requisiti di sicurezza in una specifica concordata e rifletterlo nel backlog. Deve indicare in modo esplicito gli investimenti per la sicurezza e i compromessi e i rischi che l'azienda è disposta a intraprendere se gli investimenti non sono approvati dagli stakeholder aziendali. Ad esempio, è possibile documentare la necessità di usare un web application firewall (WAF) davanti all'applicazione, ad esempio Frontdoor di Azure o gateway applicazione di Azure. Se gli stakeholder aziendali non sono pronti ad accettare il costo aggiuntivo per l'esecuzione di un WAF, è necessario accettare il rischio che gli attacchi a livello di applicazione possano essere indirizzati all'applicazione.

La raccolta dei requisiti di sicurezza è una parte fondamentale di questa fase. Senza questo sforzo, le fasi di progettazione e implementazione saranno basate su scelte non dichiarate, che possono causare lacune di sicurezza. Potrebbe essere necessario modificare l'implementazione in un secondo momento per supportare la sicurezza, che può essere costosa.

Fase di progettazione

Durante questa fase, i requisiti di sicurezza vengono convertiti in requisiti tecnici. Nella specifica tecnica documentare tutte le decisioni di progettazione per evitare ambiguità durante l'implementazione. Ecco alcune attività tipiche:

Definire la dimensione di sicurezza dell'architettura di sistema

Sovrapporre l'architettura ai controlli di sicurezza. Ad esempio, i controlli pratici sui limiti di isolamento in base alla strategia di segmentazione, i tipi di identità necessari per i componenti dell'applicazione e il tipo di metodi di crittografia da usare. Per alcune architetture di esempio, vedere le illustrazioni nelle sezioni Esempio degli articoli Gestione delle identità e degli accessi e Rete .

Valutare gli inviti forniti dalla piattaforma

È importante comprendere la divisione della responsabilità tra l'utente e il provider di servizi cloud. Evitare la sovrapposizione con i controlli di sicurezza nativi di Azure, ad esempio. Si otterrà una migliore copertura della sicurezza e sarà possibile riallocare le risorse di sviluppo alle esigenze dell'applicazione.

Ad esempio, se la progettazione chiama un web application firewall in ingresso, è possibile eseguire l'offload di tale responsabilità in un servizio di bilanciamento del carico, ad esempio gateway applicazione o Frontdoor di Azure. Evitare di replicare le funzionalità come codice personalizzato nell'applicazione.

Scegliere solo framework, librerie e software della supply chain attendibili. La progettazione deve anche specificare il controllo della versione sicuro. Le dipendenze dell'applicazione devono essere originate da parti attendibili. I fornitori di terze parti devono essere in grado di soddisfare i requisiti di sicurezza e condividere il piano di divulgazione responsabile. Qualsiasi evento imprevisto di sicurezza deve essere segnalato tempestivamente in modo da poter eseguire le azioni necessarie. Inoltre, alcune librerie potrebbero essere vietate dall'organizzazione. Ad esempio, il software potrebbe essere protetto da vulnerabilità, ma ancora non consentito a causa di restrizioni di licenza.

Per garantire che queste linee guida siano seguite da tutti i collaboratori al software, mantenere un elenco di framework, librerie e fornitori approvati e/o non approvati. Quando possibile, posizionare le protezioni nelle pipeline di sviluppo per supportare l'elenco. Il più possibile, automatizzare l'uso degli strumenti per analizzare le dipendenze per individuare le vulnerabilità.

Determinare i modelli di progettazione della sicurezza che il codice dell'applicazione deve implementare.

I modelli possono supportare problemi di sicurezza come la segmentazione e l'isolamento, l'autorizzazione avanzata, la sicurezza uniforme delle applicazioni e i protocolli moderni. Alcuni modelli operativi, ad esempio il modello di quarantena, possono aiutare a verificare e bloccare l'uso del software che potrebbe potenzialmente introdurre vulnerabilità di sicurezza.

Per altre informazioni, vedere Modelli di progettazione cloud che supportano la sicurezza.

Archiviare i segreti delle applicazioni in modo sicuro

Implementare in modo sicuro l'uso dei segreti dell'applicazione e delle chiavi precondi condivise usate dall'applicazione. Le credenziali e i segreti dell'applicazione non devono mai essere archiviati nell'albero del codice sorgente. Usare risorse esterne come Azure Key Vault per assicurarsi che, se il codice sorgente diventa disponibile per un potenziale utente malintenzionato, non è possibile ottenere altri accessi. In generale, trovare modi per evitare segreti. L'uso delle identità gestite, quando possibile, è un modo per raggiungere tale obiettivo. Per altre informazioni, vedere Raccomandazioni per la gestione dei segreti dell'applicazione.

Definire i piani di test

Definire test case chiari per i requisiti di sicurezza. Valutare se è possibile automatizzare tali test nelle pipeline. Se il team ha processi per il test manuale, includere i requisiti di sicurezza per tali test.

Nota

Eseguire la modellazione delle minacce durante questa fase. La modellazione delle minacce può confermare che le scelte di progettazione sono allineate ai requisiti di sicurezza ed espongono lacune che è necessario attenuare. Se il carico di lavoro gestisce dati estremamente sensibili, investire in esperti di sicurezza che possono aiutare a eseguire la modellazione delle minacce.

L'esercizio iniziale di modellazione delle minacce deve verificarsi durante la fase di progettazione quando viene definita l'architettura del software e la progettazione di alto livello. Questa operazione durante questa fase consente di identificare potenziali problemi di sicurezza prima che vengano incorporati nella struttura del sistema. Tuttavia, questo esercizio non è un'attività monouso. Si tratta di un processo continuo che deve continuare per tutta l'evoluzione del software.

Per altre informazioni, vedere Raccomandazioni per l'analisi delle minacce.

Fase di sviluppo e test

Durante questa fase, l'obiettivo è prevenire difetti di sicurezza e manomissioni nel codice, nella compilazione e nelle pipeline di distribuzione.

Essere ben addestrati nelle procedure di codice sicure

Il team di sviluppo deve avere una formazione formale e specializzata in procedure di codifica sicure. Ad esempio, gli sviluppatori di API e Web potrebbero avere bisogno di formazione specifica per la protezione da attacchi di scripting tra siti e sviluppatori back-end possono trarre vantaggio dal training approfondito per evitare attacchi a livello di database come attacchi SQL injection.

Gli sviluppatori devono essere tenuti a completare questo training prima di poter accedere al codice sorgente di produzione.

È anche consigliabile eseguire revisioni del codice peer interne per promuovere l'apprendimento continuo.

Usare gli strumenti di test di sicurezza

Eseguire la modellazione delle minacce per valutare la sicurezza dell'architettura dell'applicazione.

Usare i test di sicurezza delle applicazioni statici (SAST) per analizzare il codice per individuare le vulnerabilità. Integrare questa metodologia nell'ambiente di sviluppo per rilevare le vulnerabilità in tempo reale.

Usare test di sicurezza delle applicazioni dinamici (DAST) durante il runtime. Questa catena di strumenti può verificare la presenza di errori nei domini di sicurezza e simulare un set di attacchi per testare la resilienza della sicurezza dell'applicazione. Quando possibile, integrare questo strumento nelle pipeline di compilazione.

Seguire gli standard di settore per procedure di codifica sicure. Per altre informazioni, vedere la sezione Risorse della community di questo articolo.

Usare linters e analizzatori di codice per impedire il push delle credenziali nel repository del codice sorgente. Ad esempio, gli analizzatori di .NET Compiler Platform (Roslyn) controllano il codice dell'applicazione.

Durante il processo di compilazione, usare i componenti aggiuntivi della pipeline per intercettare le credenziali nel codice sorgente. Analizzare tutte le dipendenze, ad esempio librerie di terze parti e componenti del framework, come parte del processo di integrazione continua. Analizzare i componenti vulnerabili contrassegnati dallo strumento. Combinare questa attività con altre attività di analisi del codice che controllano la varianza del codice, i risultati dei test e il code coverage.

Usare una combinazione di test. Per informazioni sui test di sicurezza in generale, vedere Raccomandazioni per i test di sicurezza.

Scrivere codice sufficiente

Quando si riduce il footprint del codice, si riducono anche le probabilità di difetti di sicurezza. Riutilizzare codice e librerie già in uso e che sono stati sottoposti a convalide di sicurezza anziché duplicare il codice.

Sfruttare le funzionalità di Azure è un altro modo per evitare codice non necessario. Un modo consiste nell'usare i servizi gestiti. Per maggiori informazioni, vedere Usare opzioni platform as a service (PaaS).

Scrivere codice con un approccio deny-all per impostazione predefinita. Creare elenchi consentiti solo per le entità che richiedono l'accesso. Ad esempio, se si dispone di codice che deve determinare se un'operazione con privilegi deve essere consentita, è necessario scriverla in modo che il risultato di negazione sia il caso predefinito e che il risultato di consenti si verifichi solo quando è consentito in modo specifico dal codice.

Proteggere gli ambienti di sviluppo

Le workstation per sviluppatori devono essere protette con controlli di rete e identità sicuri per evitare l'esposizione. Assicurarsi che gli aggiornamenti della sicurezza vengano applicati in modo diligente.

Gli agenti di compilazione hanno privilegi elevati e hanno accesso al server di compilazione e al codice. Devono essere protetti con lo stesso rigore dei componenti del carico di lavoro. Ciò significa che l'accesso agli agenti di compilazione deve essere autenticato e autorizzato, deve essere segmentato dalla rete con controlli firewall, deve essere soggetto all'analisi delle vulnerabilità e così via. Gli agenti di compilazione ospitati da Microsoft devono essere preferiti rispetto agli agenti di compilazione self-hosted. Gli agenti ospitati da Microsoft offrono vantaggi come macchine virtuali pulite per ogni esecuzione di una pipeline.

Gli agenti di compilazione personalizzati aggiungono complessità di gestione e possono diventare un vettore di attacco. Le credenziali del computer di compilazione devono essere archiviate in modo sicuro ed è necessario rimuovere regolarmente eventuali artefatti di compilazione temporanei dal file system. È possibile ottenere l'isolamento della rete consentendo solo il traffico in uscita dall'agente di compilazione, perché usa il modello di comunicazione pull con Azure DevOps.

È necessario proteggere anche il repository del codice sorgente . Concedere l'accesso ai repository di codice in base alla necessità e ridurre il più possibile l'esposizione delle vulnerabilità per evitare attacchi. È necessario un processo completo per esaminare il codice per individuare le vulnerabilità di sicurezza. Usare i gruppi di sicurezza a tale scopo e implementare un processo di approvazione basato sulle motivazioni aziendali.

Distribuzioni di codice sicure

Non è sufficiente proteggere il codice. Se viene eseguito in pipeline sfruttabili, tutte le attività di sicurezza sono inutili e incomplete. Gli ambienti di compilazione e rilascio devono anche essere protetti perché si vuole impedire agli attori malintenzionati di eseguire codice dannoso nella pipeline.

Mantenere un inventario aggiornato di ogni componente integrato nell'applicazione

Ogni nuovo componente integrato in un'applicazione aumenta la superficie di attacco. Per garantire una corretta responsabilità e avvisi quando vengono aggiunti o aggiornati nuovi componenti, è necessario disporre di un inventario di questi componenti. Archiviarlo all'esterno dell'ambiente di compilazione. A intervalli regolari, verificare che il manifesto corrisponda a ciò che si trova nel processo di compilazione. In questo modo si garantisce che non vengano aggiunti in modo imprevisto nuovi componenti che contengono backdoor o altri malware.

Attività della pipeline

  • Eseguire il pull delle attività nella pipeline da origini attendibili, ad esempio Azure Marketplace. Eseguire attività scritte dal fornitore della pipeline. È consigliabile eseguire attività o GitHub Actions di GitHub. Se si usano flussi di lavoro di GitHub, preferire le attività create da Microsoft. Convalidare anche le attività perché vengono eseguite nel contesto di sicurezza della pipeline.

  • Segreti della pipeline. Gli asset di distribuzione eseguiti all'interno di una pipeline hanno accesso a tutti i segreti in tale pipeline. Disporre di una segmentazione corretta per diverse fasi della pipeline per evitare l'esposizione non necessaria. Usare gli archivi segreti incorporati nella pipeline. Tenere presente che è possibile evitare di usare i segreti in alcune situazioni. Esplorare l'uso delle identità del carico di lavoro (per l'autenticazione della pipeline) e delle identità gestite (per l'autenticazione da servizio a servizio).

Mantenere separati gli ambienti diversi

I dati usati in ambienti diversi devono essere mantenuti separati. I dati di produzione non devono essere usati in ambienti inferiori perché tali ambienti potrebbero non avere i controlli di sicurezza rigorosi di cui dispone la produzione. Evitare di connettersi da un'applicazione non di produzione a un database di produzione ed evitare la connessione di componenti non di produzione alle reti di produzione.

Esposizione progressiva

Usare l'esposizione progressiva per rilasciare le funzionalità a un subset di utenti in base ai criteri scelti. In caso di problemi, l'impatto viene ridotto al minimo per tali utenti. Questo approccio è una strategia comune di mitigazione dei rischi perché riduce la superficie di attacco. Man mano che la funzionalità si matura e si ha maggiore fiducia nelle garanzie di sicurezza, è possibile rilasciarla gradualmente in un set più ampio di utenti.

Fase di produzione

La fase di produzione rappresenta l'ultima opportunità responsabile per correggere i gap di sicurezza. Mantenere un record dell'immagine d'oro rilasciata nell'ambiente di produzione.

Mantenere gli artefatti con controllo delle versioni

Mantenere un catalogo di tutti gli asset distribuiti e le relative versioni. Queste informazioni sono utili durante la valutazione degli eventi imprevisti, quando si attenuano i problemi e quando si torna allo stato di funzionamento del sistema. Gli asset con controllo delle versioni possono anche essere confrontati con gli avvisi cve (Common Vulnerabilities and Exposures) pubblicati. È consigliabile usare l'automazione per eseguire questi confronti.

Correzioni di emergenza

La progettazione automatizzata della pipeline deve avere la flessibilità necessaria per supportare le distribuzioni regolari e di emergenza. Questa flessibilità è importante per supportare correzioni di sicurezza rapide e responsabili.

Una versione è in genere associata a più controlli di approvazione. Prendere in considerazione la creazione di un processo di emergenza per accelerare le correzioni di sicurezza. Il processo potrebbe comportare la comunicazione tra i team. La pipeline deve consentire distribuzioni rapide di roll forward e rollback che consentono correzioni di sicurezza, bug critici e aggiornamenti del codice che si verificano al di fuori del ciclo di vita normale della distribuzione.

Nota

Assegnare sempre priorità alle correzioni di sicurezza sulla praticità. Una correzione di sicurezza non deve introdurre una regressione o un bug. Se si vuole accelerare la correzione tramite una pipeline di emergenza, valutare attentamente quali test automatizzati possono essere ignorati. Valutare il valore di ogni test rispetto al tempo di esecuzione. Ad esempio, gli unit test vengono in genere completati rapidamente. I test end-to-end o di integrazione possono essere eseguiti per molto tempo.

Fase di manutenzione

L'obiettivo di questa fase è assicurarsi che il comportamento di sicurezza non decadi nel tempo. SDLC è un processo agile in corso. I concetti illustrati nelle fasi precedenti si applicano a questa fase perché i requisiti cambiano nel tempo.

Gestione delle patch. Mantenere aggiornati software, librerie e componenti dell'infrastruttura con patch di sicurezza e aggiornamenti.

Miglioramento continuo. Valutare e migliorare continuamente la sicurezza del processo di sviluppo software tenendo conto delle revisioni del codice, del feedback, delle lezioni apprese e delle minacce in evoluzione.

Rimuovere gli asset legacy non aggiornati o non più in uso. In questo modo si riduce l'area di superficie dell'applicazione.

La manutenzione include anche correzioni degli eventi imprevisti. Se i problemi si trovano nell'ambiente di produzione, devono essere integrati tempestivamente nel processo in modo che non vengano ricorsi.

Migliorare continuamente le procedure di codifica sicure per mantenere il panorama delle minacce.

Facilitazione di Azure

Microsoft Security Development Lifecycle (SDL) consiglia procedure sicure che è possibile applicare al ciclo di vita dello sviluppo. Per altre informazioni, vedere Ciclo di vita dello sviluppo della sicurezza Microsoft.

Defender per DevOps e gli strumenti SAST sono inclusi come parte di GitHub Advanced Security o Azure DevOps. Questi strumenti consentono di tenere traccia di un punteggio di sicurezza per l'organizzazione.

Seguire le raccomandazioni sulla sicurezza di Azure descritte in queste risorse:

Per trovare le credenziali nel codice sorgente, prendere in considerazione l'uso di strumenti come GitHub Advanced Security e strumenti di analisi del codice sorgente OWASP.

Convalidare la sicurezza di qualsiasi codice open source nell'applicazione. Questi strumenti e risorse gratuite possono essere utili per la valutazione:

Elenco di controllo relativo alla sicurezza

Fare riferimento al set completo di raccomandazioni.