Procedure consigliate per una catena di approvvigionamento del software sicura

Open Source è ovunque. Si trova in molte codebase proprietarie e progetti della community. Per le organizzazioni e le persone, la domanda odierna non è se si sta usando codice open source, ma quale codice open source si sta usando e quanto.

Se non si è consapevoli di ciò che si trova nella supply chain del software, una vulnerabilità upstream in una delle dipendenze può essere fatale, esponendo sia te che i tuoi clienti a un potenziale compromesso. In questo documento verranno approfonditi i termini "catena di approvvigionamento software", perché è importante e come è possibile proteggere la supply chain del progetto con le procedure consigliate.

Lo stato dell'Octoverse 2020 - Open Source

Dipendenze

Il termine catena di approvvigionamento software viene usato per fare riferimento a tutto ciò che entra nel software e da dove proviene. Si tratta delle dipendenze e delle proprietà delle dipendenze da cui dipende la supply chain del software. Una dipendenza è ciò di cui il tuo software ha bisogno per funzionare. Può essere codice, file binari o altri componenti e da dove provengono, ad esempio un repository o una gestione pacchetti.

Include chi ha scritto il codice, quando è stato contribuito, come è stato esaminato per problemi di sicurezza, vulnerabilità note, versioni supportate, informazioni sulle licenze e solo qualsiasi elemento che lo tocca in qualsiasi punto del processo.

La supply chain comprende anche altre parti dello stack oltre una singola applicazione, ad esempio gli script di compilazione e creazione di pacchetti o il software che esegue l'infrastruttura su cui si basa l'applicazione.

Vulnerabilità

Oggi, le dipendenze software sono diffuse. È piuttosto comune per i progetti usare centinaia di dipendenze open source per le funzionalità che non è necessario scrivere manualmente. Ciò può significare che la maggior parte dell'applicazione è costituita da codice che non è stato creato.

Stato dell'Octoverse 2020 - Dipendenze

Le possibili vulnerabilità nelle dipendenze open source o di terze parti sono presumibilmente dipendenze che non è possibile controllare altrettanto strettamente come il codice scritto, che può creare potenziali rischi per la sicurezza nella catena di fornitura.

Se una di queste dipendenze presenta una vulnerabilità, è probabile che tu abbia anche una vulnerabilità. Questo può essere spaventoso perché una delle dipendenze può cambiare senza neanche sapere. Anche se una vulnerabilità esiste attualmente in una dipendenza, ma non è sfruttabile, può essere sfruttata in futuro.

Essere in grado di sfruttare il lavoro di migliaia di sviluppatori e autori di librerie open source significa che migliaia di sconosciuti possono contribuire in modo efficace direttamente al codice di produzione. Il tuo prodotto, attraverso la catena di fornitura del software, è soggetto a vulnerabilità non corrette, errori innocenti o persino attacchi dannosi contro le dipendenze.

Compromissioni della catena di approvvigionamento

La definizione tradizionale di una catena di approvvigionamento deriva dalla produzione; è la catena di processi necessari per fare e fornire qualcosa. Include pianificazione, fornitura di materiali, produzione e vendita al dettaglio. Una catena di approvvigionamento software è simile, tranne che invece di materiali, è codice. Invece di produrre, si tratta di sviluppo. Invece di scavare il minerale dal suolo, il codice viene originato da fornitori, commerciali o open source e, in generale, il codice open source proviene da repository. L'aggiunta di codice da un repository significa che il prodotto assume una dipendenza da tale codice.

Un esempio di attacco della supply chain software si verifica quando il codice dannoso viene aggiunto intenzionalmente a una dipendenza, usando la catena di fornitura di tale dipendenza per distribuire il codice alle vittime. Gli attacchi alla catena di approvvigionamento sono reali. Esistono molti metodi per attaccare una supply chain, dall'inserimento diretto di codice dannoso come nuovo collaboratore, all'acquisizione dell'account di un collaboratore senza che altri utenti notino o persino compromettendo una chiave di firma per distribuire software che non fa ufficialmente parte della dipendenza.

Un attacco a catena di approvvigionamento software è in e di se stesso raramente l'obiettivo finale, piuttosto è l'inizio di un'opportunità per un utente malintenzionato di inserire malware o fornire un backdoor per l'accesso futuro.

The State of the Octoverse 2020 - Vulnerability LifecycleStato di Octoverse 2020 - Ciclo di vita della vulnerabilità

Software senza patch

L'uso di open source oggi è significativo e non si prevede di rallentare in qualsiasi momento presto. Dato che non smettiamo di usare software open source, la minaccia per la sicurezza della catena di approvvigionamento è un software senza patch. In che modo è possibile affrontare il rischio che una dipendenza del progetto abbia una vulnerabilità?

  • Sapere cosa si trova nell'ambiente. Ciò richiede l'individuazione delle dipendenze e le eventuali dipendenze transitive per comprendere i rischi di tali dipendenze, ad esempio vulnerabilità o restrizioni di licenza.
  • Gestire le dipendenze. Quando viene individuata una nuova vulnerabilità di sicurezza, è necessario determinare se si è interessati e, in tal caso, eseguire l'aggiornamento alla versione più recente e alla patch di sicurezza disponibile. Ciò è particolarmente importante per esaminare le modifiche che introducono nuove dipendenze o controllano regolarmente le dipendenze meno recenti.
  • Monitorare la catena di approvvigionamento. Questo avviene controllando i controlli disponibili per gestire le dipendenze. Questo ti aiuterà ad applicare condizioni più restrittive da soddisfare per le tue dipendenze.

The State of the Octoverse 2020 - AdvisoriesStato dell'octoverse 2020 - Avvisi

Verranno illustrati vari strumenti e tecniche forniti da NuGet e GitHub, che è possibile usare oggi per affrontare i potenziali rischi all'interno del progetto.

Conoscenza di ciò che si trova nell'ambiente

Pacchetti con vulnerabilità note

📦 Consumer di pacchetti | 📦🖊 Autore del pacchetto

.NET 8 e Visual Studio 17.8 hanno aggiunto NuGetAudit, che avviserà di pacchetti diretti con vulnerabilità note durante il processo di ripristino. .NET 9 e Visual Studio 17.12 hanno modificato l'impostazione predefinita per avvisare anche i pacchetti transitivi.

NuGetAudit richiede un'origine per fornire un database di vulnerabilità conosciute, quindi se non usi nuget.org come origine del pacchetto, dovresti aggiungerla come sorgente di verifica.

Quando NuGet avvisa l'utente, la vulnerabilità è nota pubblicamente. Gli utenti malintenzionati possono usare questa divulgazione pubblica per sviluppare attacchi per destinazioni che non hanno eseguito patch alle applicazioni. Pertanto, quando viene visualizzato un avviso che indica che un pacchetto usato dal progetto presenta una vulnerabilità nota, è consigliabile intervenire rapidamente.

Grafico delle dipendenze NuGet

📦 Consumatore di pacchetti

È possibile visualizzare le dipendenze NuGet nel progetto esaminando direttamente il rispettivo file di progetto.

Questo si trova in genere in una delle due posizioni seguenti:

  • packages.config: si trova nella directory principale del progetto.
  • : si trova nel file di progetto.

A seconda del metodo usato per gestire le dipendenze di NuGet, è anche possibile usare Visual Studio per visualizzare le dipendenze direttamente in Esplora soluzioni o Gestione pacchetti NuGet.

Per ambienti CLI, è possibile utilizzare il comando per elencare le dipendenze del progetto o della soluzione. È anche possibile usare il comando per comprendere perché i pacchetti transitivi (quelli non direttamente referenziati dal tuo progetto) siano inclusi nel grafo di dipendenze del pacchetto del progetto.

Per ulteriori informazioni sulla gestione delle dipendenze NuGet, vedere la seguente documentazione .

Grafico delle dipendenze di GitHub

📦 Consumatore di pacchetti | 📦🖊 Autore dei pacchetti

È possibile usare il grafico delle dipendenze di GitHub per visualizzare i pacchetti da cui dipende il progetto e dai repository che dipendono da esso. Ciò consente di visualizzare eventuali vulnerabilità rilevate nelle relative dipendenze.

Per ulteriori informazioni sulle dipendenze del repository GitHub, vedi la documentazione seguente.

Versioni delle dipendenze

Consumatore di pacchetti | Autore di pacchetti

Per garantire una catena di approvvigionamento sicura delle dipendenze, è necessario assicurarsi che tutte le dipendenze e gli strumenti vengano aggiornati regolarmente alla versione stabile più recente, perché spesso includono le funzionalità più recenti e le patch di sicurezza per le vulnerabilità note. Le tue dipendenze possono includere il codice da cui dipendi, i file binari che consumi, gli strumenti che utilizzi e altri componenti. Possono includere:

Gestire le dipendenze

Dipendenze deprecate e vulnerabili di NuGet

Consumatore di pacchetto | Autore dei pacchetti

È possibile utilizzare la CLI di dotnet per elencare qualsiasi dipendenza deprecata o vulnerabile presente nel progetto o nella soluzione. È possibile utilizzare il comando dotnet list package --deprecated o dotnet list package --vulnerable per fornire un elenco di eventuali deprecazioni o vulnerabilità note. NuGetAudit può avvisarti sulle dipendenze vulnerabili note ed è abilitato per impostazione predefinita quando una fonte fornisce un database di vulnerabilità.

Dipendenze vulnerabili di GitHub

📦 Consumer di pacchetto | 📦🖊 Autore del pacchetto

Se il tuo progetto è ospitato su GitHub, puoi sfruttare GitHub Security per trovare vulnerabilità e errori di sicurezza nel tuo progetto e Dependabot li correggerà aprendo una pull request sulla tua codebase.

Intercettare le dipendenze vulnerabili prima che vengano introdotte è un obiettivo del movimento "Shift Left". La possibilità di avere informazioni sulle dipendenze, ad esempio la licenza, le dipendenze transitive e l'età delle dipendenze consente di farlo.

Per ulteriori informazioni sugli avvisi di Dependabot e sugli aggiornamenti di sicurezza, consulta la seguente documentazione.

Configurazione di NuGet

Consumatore di pacchetti

Aggiungere un nuget.config file nella radice del repository del progetto. Questa procedura è considerata una procedura consigliata perché promuove la ripetibilità e garantisce che diversi utenti abbiano la stessa configurazione NuGet. È consigliabile aggiungere clear elementi per assicurarsi che non venga applicata alcuna configurazione specifica dell'utente o del computer. Altre informazioni su come vengono applicate le impostazioni.

Per esempio:

<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceMapping>
    <clear />
  </packageSourceMapping>
</configuration>

Tip

Se l'organizzazione blocca l'accesso a api.nuget.org, è consigliabile chiedere all'amministratore di rete di consentire https://data.nuget.org/v3/index.json e configurarlo come origine di controllo per Il controllo NuGet. Questo endpoint serve solo i dati di vulnerabilità, non i pacchetti, quindi potrebbe essere consentito anche quando api.nuget.org viene bloccato.

Feed NuGet

Consumatore di pacchetti

Usare fonti di pacchetti di cui ci si fida. Quando si usano più feed di origine NuGet pubblici e privati, è possibile scaricare un pacchetto da uno dei feed. Per garantire che la compilazione sia prevedibile e sicura da attacchi noti come Dependency Confusion, sapere da dove provengono specificamente i feed dei pacchetti è una buona prassi. È possibile usare un singolo feed o feed privato con funzionalità di upstreaming per la protezione.

Per ulteriori informazioni su come proteggere i feed dei pacchetti, consulta 3 Modi per mitigare i rischi quando si usano i feed privati di pacchetti.

Quando si usa un feed privato, consultare le procedure consigliate per la sicurezza per la gestione delle credenziali.

Criteri di attendibilità client

Consumatore di pacchetti

Esistono criteri in cui è possibile acconsentire esplicitamente in cui è necessario che i pacchetti usati siano firmati. In questo modo è possibile considerare attendibile un autore del pacchetto, purché sia firmato dall'autore o considerare attendibile un pacchetto se è di proprietà di un utente o di un account specifico firmato da NuGet.org.

Per configurare i criteri di attendibilità client, vedere la documentazione seguente.

File di blocco

Consumatore di pacchetti

I file di blocco archiviano l'hash del contenuto del pacchetto. Se l'hash del contenuto di un pacchetto che si vuole installare corrisponde al file di blocco, garantisce la ripetibilità dei pacchetti.

Per abilitare i file di blocco, consultare la documentazione seguente.

Mappatura delle origini del pacchetto

Consumatore di pacchetti

La mappatura dell'origine dei pacchetti consente di dichiarare centralmente da quale origine ripristinare ogni pacchetto nella soluzione nel file nuget.config.

Per abilitare il mapping dell'origine dei pacchetti, consultare la seguente documentazione.

Computer sicuri

Autorizzazioni della directory

Consumatore di pacchetti

In Windows e Mac e alcune distribuzioni Linux, le home directory dell'account utente sono private per impostazione predefinita. Tuttavia, alcune distribuzioni Linux rendono leggibili le directory utente da altri account nello stesso computer per impostazione predefinita. Inoltre, sono disponibili diverse opzioni di configurazione per reindirizzare la cartella dei pacchetti globali di NuGet e la cache HTTP verso percorsi non predefiniti. È anche possibile creare soluzioni, progetti e repository all'esterno della home directory dell'utente.

Se si usano pacchetti non presenti in nuget.org, se un altro account nel computer può leggere i pacchetti globali o le directory della cache HTTP di NuGet o la directory di output della compilazione del progetto, questi pacchetti potrebbero essere divulgati agli utenti che non devono avere accesso a tali pacchetti.

In Linux, dotnet nuget update source cambierà le autorizzazioni del file nuget.config per renderlo leggibile solo dal proprietario. Tuttavia, se si modifica il file nuget.config in qualsiasi altro modo e il file si trova in un percorso in cui altri account possono leggere il file, potrebbe esserci una divulgazione di informazioni sull'URL dell'origine del pacchetto o sulle credenziali dell'origine del pacchetto. È necessario assicurarsi che qualsiasi file nuget.config non possa essere letto da altri utenti dello stesso computer.

Soluzioni all'interno della directory di download

Consumatore di pacchetti

Occorre prestare particolare attenzione se si lavora su soluzioni o progetti nella directory dei download. NuGet accumulerà le impostazioni dai diversi file di configurazione e MSBuild in genere importerà Directory.Build.props, Directory.NuGet.props, Directory.Build.targets, e potenzialmente altri file, da qualsiasi directory padre, fino alla radice del file system.

La cartella download ha un rischio aggiuntivo, poiché è in genere il percorso predefinito in cui i Web browser scaricherà i file da Internet

Agenti di compilazione

Consumatore di pacchetti

Gli agenti di compilazione (agenti CI) che non vengono reimpostati su uno stato iniziale dopo che ogni compilazione presenta più rischi che devono essere considerati.

Per informazioni su modi sicuri per gestire le credenziali, vedere la documentazione sui pacchetti da feed autenticati.

Per informazioni sulla modifica delle directory in cui NuGet archivia i dati, consultare la documentazione sulla gestione dei pacchetti globali, della cache e delle cartelle temporanee. Queste directory devono essere configurate in una directory che l'agente di integrazione continua pulisce dopo ogni build.

Si noti che tutti i pacchetti usati dal progetto potrebbero essere lasciati nella directory di output della compilazione del progetto. Se il progetto usa pacchetti da origini autenticate, altri utenti dello stesso agente CI potrebbero ottenere l'accesso non autorizzato agli assembly del pacchetto. Pertanto, è consigliabile pulire anche il repository alla fine della compilazione, anche quando la compilazione non riesce o viene annullata.

Monitorare la catena di approvvigionamento

scansione dei segreti di GitHub

Autore del pacchetto

GitHub analizza i repository alla ricerca di chiavi API NuGet per evitare usi fraudolenti di segreti che sono stati accidentalmente commessi.

Per altre informazioni sull'analisi dei segreti, vedere Informazioni sull'analisi dei segreti.

Firma del pacchetto dell'autore

📦🖊 Autore del pacchetto

La firma dell'autore consente a un autore del pacchetto di contrassegnare la propria identità su un pacchetto e a un consumatore di verificare che proviene dal mittente. Questo ti protegge dalle manomissioni dei contenuti e funge da singola fonte di verità sull'origine del pacchetto e sull'autenticità del pacchetto. In combinazione con i criteri di attendibilità client, è possibile verificare che un pacchetto provenisse da un autore specifico.

Per creare la firma di un pacchetto, vedere Firmare un pacchetto.

Compilazioni riproducibili

📦🖊 Autore del pacchetto

Le compilazioni riproducibili creano file binari che sono byte per byte identici ogni volta che lo si compila e contengono collegamenti al codice sorgente e metadati del compilatore che consentono a un consumer di pacchetti di ricreare direttamente il file binario e verificare che l'ambiente di compilazione non sia stato compromesso.

Per altre informazioni sulle compilazioni riproducibili, vedere Produzione di pacchetti con Source Link e la specifica di convalida delle build riproducibili.

Autenticazione Two-Factor (2FA)

📦🖊 Autore del Pacchetto

Per ogni account in nuget.org è abilitata la funzionalità 2FA. Ciò aggiunge uno strato extra di sicurezza quando accedi al tuo account GitHub o al tuo account NuGet.org.

Prenotazione del prefisso dell'ID del pacchetto

📦🖊 Autore del Pacchetto

Per proteggere l'identità dei tuoi pacchetti, puoi riservare un prefisso ID pacchetto nel namespace rispettivo, per associare un proprietario corrispondente se il tuo prefisso ID pacchetto rispetta i criteri specificati.

Per informazioni sulla prenotazione dei prefissi ID, vedere Prenotazione del prefisso ID del pacchetto.

Deprecazione e annullamento dell'elenco di un pacchetto vulnerabile

📦🖊 Autore del pacchetto

Per proteggere l'ecosistema di pacchetti .NET quando si è a conoscenza di una vulnerabilità in un pacchetto creato, è consigliabile deprecare e rimuovere l'elenco del pacchetto in modo che sia nascosto agli utenti che cercano pacchetti. Se si utilizza un pacchetto deprecato e non elencato, è consigliabile evitare di usare il pacchetto.

Per informazioni su come deprecare e rimuovere l'elenco di un pacchetto, vedere la documentazione seguente sulla deprecazione e l'annullamento dell'elenco dei pacchetti.

Prendere in considerazione anche la possibilità di segnalare le informazioni note al Database degli Avvisi di GitHub.

Riepilogo

La supply chain del software è qualsiasi elemento che entra o influisce sul codice. Anche se i compromessi della supply chain sono reali e in crescita in popolarità, sono ancora rari; quindi la cosa più importante che è possibile fare è proteggere la supply chain conoscendo le dipendenze, gestendo le dipendenze e monitorando la catena di approvvigionamento.

Hai appreso vari metodi che NuGet e GitHub forniscono e che sono attualmente disponibili per migliorare l'efficacia nella visualizzazione, gestione e monitoraggio della catena di fornitura.

Per altre informazioni sulla protezione del software mondiale, vedere The State of the Octoverse 2020 Security Report.