CICD-Pipelines-Vulnerabilità

Un tuffo profondo CI/CD Pipelines Vulnerabilità (IV): protezione dall'avvelenamento da artefatti tramite attestazioni software

Nel nostro post precedente su CI/CD Pipelines, vedemmo come hackerare un CI/CD scenario che presumibilmente era protetto.

Ricordiamo il punto del post precedente: abbiamo iniziato con alcuni pipeline a cui era vulnerabile Avvelenato indiretto Pipeline (I-PPE) e, per rimediare, abbiamo deciso di frazionare il pipeline in due:

  • il 1st pipeline (Build CI), sicuro per D-PPE e I-PPE, estrarrebbe il codice PR, realizzerebbe la build e genererebbe un artefatto
  • L'2nd pipeline (Test CI), sicuro anche per D-PPE e I-PPE, effettuerebbe il checkout del codice Base (per evitare la modifica dello script di shell) ed eseguirebbe gli script originali sull'artefatto. 
  • Per sincronizzare il test CI pipeline da eseguire DOPO la build CI pipeline, abbiamo usato flusso di lavoro_esegui grilletto. 

Lo abbiamo chiamato Scenario n. 3.

CICD-Sicurezza

Sebbene, come abbiamo accennato in quel post, esistano altre soluzioni, abbiamo deciso di implementare questa “soluzione” per ragioni pedagogiche, in modo da poter approfondire le vulnerabilità di CI/CD pipelines.

Successivamente, abbiamo visto come hackerare questo scenario avvelenare il manufatto. Questo è ciò che chiamiamo Avvelenamento da artefatto, ovvero la possibilità di modificare (hackerare) il file pipeline logica modificando a pipeline artefatto.

Qual è il problema con questo approccio? Abbiamo visto che il problema sorge quando un qualsiasi utente “crea” un nuovo file pipeline. 

Se un utente apre un PR contenente un nuovo file pipeline, GitHub lo eseguirà pipeline  (date alcune condizioni, come abbiamo visto nella posta).

L'utente è quindi in grado di crearne uno nuovo pipeline con lo stesso nome di Build CI!! Sì, è sorprendente, ma GitHub ti permette di crearne due pipelineha lo stesso nome!!

Quando l'utente apre un PR con queste modifiche, il nuovo" pipeline verrà eseguito (caricando un artefatto avvelenato) e l'IC di distribuzione pipeline verrà eseguito successivamente, con il risultato che lo script di shell "modificato" sovrascriverà lo script di shell "originale" situato nel file pipeline spazio di lavoro. Quindi, questa “soluzione” non evita la vulnerabilità I-PPE (come possiamo vedere di seguito)

CICD-Pipelines

Quali sono i problemi? Almeno ci sono un paio di problemi:

  1. In primo luogo, come essere sicuri che il processo di compilazione non sia stato manomesso? In questo scenario, l'utente malintenzionato è riuscito a modificare il processo di compilazione previsto utilizzando il proprio file pipeline per creare un artefatto avvelenato.
  2. In secondo luogo, come possiamo valutare la provenienza di un manufatto?

Queste domande ci gettano tra le braccia del Attestazioni software dominio!!

Attestazioni software

An attestazione è un pezzo di dati che rappresenta prova di un evento. Nel mondo reale, generalmente li chiamiamo certificazioni.

Ad esempio, quando un laboratorio analizza il sangue, i dati relativi al test vengono registrati e certificati. I risultati degli esami del sangue sono verificabile and tracciabile.

Software_Supply_Chain_Attestations

Più vicino al nostro dominio IT, potresti immaginare quale sarebbe una traduzione di questo processo, ad esempio, in un processo di compilazione.

Attestazioni_software

Le informazioni sull'ambiente e sugli strumenti del server di compilazione, sui materiali (il codice sorgente) e sui prodotti/artefatti (il codice binario) faranno parte di tale attestazione.

Ovviamente l'attestazione deve essere generata da un attestatore autorizzato (autenticato e non ripudiabile) per fornire credibilità. 

Probabilmente, alcuni di voi potrebbero pensare... e qual è il differenza tra firme e attestazioni?

Firme e attestazioni del codice

Ad alto livello, a firma viene creato utilizzando una coppia di chiavi e un artefatto. La coppia di chiavi è composta da una chiave pubblica e una chiave privata. 

Firme in codice

L'utente firma un artefatto utilizzando la chiave privata e altri possono quindi verificare la firma utilizzando la chiave pubblica. La chiave privata deve essere mantenuta segreta, ma la chiave pubblica è ampiamente distribuita.

È possibile utilizzare le firme per dimostrare che il titolare della chiave privata ha utilizzato la chiave privata per firmare l'artefatto

firme non dimostrare 

  • L'utente Intenzione firmare l'artefatto (potrebbero essere stati ingannati), oppure 
  • L'intenzione dell'utente di effettuare qualsiasi affermazione specifica sul manufatto 

Con attestazioni, invece di firmare direttamente un artefatto, gli utenti creano una sorta di documento che coglie il loro intento dietro la firma del manufatto e quant'altro affermazioni specifiche essere fatto come parte di questa firma.

Quadro di attestazione in-toto

Il quadro più comune è il Quadro di attestazione in-toto

  • definisce standard formato per attestazioni che legano i soggetti, gli artefatti descritti, ai metadati autenticati sull'artefatto 
  • fornisce una serie di predicati predefiniti per la comunicazione di metadati autenticati attraverso le catene di fornitura del software

Andiamo più nel dettaglio sul formato dell'attestazione.

An attestazione è un documento firmato digitalmente che contiene Dichiarazioni.

Migliori dichiarazione è lo strato intermedio dell'attestazione, legandola ad un particolare Oggetto e identificando in modo inequivocabile i tipi di Predicato:

  • Oggetto: L' riferimento crittograficamente sicuro all'artefatto (di solito tramite un hash) e
  • predicati: un insieme di specifici riguardo a quell'artefatto viene definito Dichiarazione. Queste affermazioni possono essere utilizzate per esprimere (e successivamente dimostrare) qualsiasi cosa tu possa pensare! Possono rappresentare l'approvazione manuale, la provenienza degli artefatti, i risultati dei test automatizzati, una traccia di controllo o altro! 

Quando questa Dichiarazione è firmata crittograficamente, viene denominata an attestazione

CI/CD_Scenario_di_sicurezza_3

In questo modo, ad esempio, Alice crea uno Statement relativo ad un artefatto e lo firma utilizzando la sua chiave privata, creando un'Attestation.

  • Bob può allora verificare la firma in quella Attestazione, permettendoglielo fidarsi delle affermazioni dentro. 

Bob può quindi utilizzare tali affermazioni decidere se consentire o meno l'utilizzo di questo artefatto.

Attestazioni_software_Gr

Le attestazioni potrebbero aiutare a risolvere l'avvelenamento da artefatti?

Dopo questa introduzione alle Attestazioni, torniamo al nostro problema. In che modo le attestazioni possono aiutarci a risolvere il nostro problema, ovvero a evitare l'avvelenamento degli artefatti?

L'utente malintenzionato è riuscito a creare un artefatto bypassando il meccanismo “ufficiale”, ovvero utilizzando il suo pipeline per generare l'artefatto. 

Sarebbe fantastico se potessimo dimostrare che gli artefatti scaricati sono stati costruiti con il funzionario pipelineS. Questo è solo un esempio di quelli che potremmo chiamare “Punti di Manomissione”, ma potrebbero essercene molti altri.

SSCS_Punti_di_manomissione

Come puoi vedere nell'immagine sopra, i punti di manomissione sono molteplici. In questo modo, il consumatore pipeline (Test CI nel nostro esempio) deve valutare il integrità del processo di costruzione nonché integrità del manufatto stesso.

Nel nostro esempio, l'artefatto avvelenato è stato creato introducendo un nuovo artefatto (avvelenato) pipeline che manomette il processo di creazione. Ma l'utente malintenzionato avrebbe potuto:

  • modificare il codice dopo averlo estratto dal SCM per generare un binario dannoso
  • sostituire il binario corretto prodotto dalla compilazione con qualsiasi altro binario dannoso
  • compromettere il registro degli artefatti e caricare un artefatto avvelenato costruito in qualsiasi altro modo
  • ecc.

 Come puoi vedere, potrebbero esserci più punti di "manomissione".

Cosa è importante qui? Ovviamente per proteggere tutti quei punti di “manomissione”. Ma, alla fine, ciò che è più importante è che il “consumatore” dell'artefatto possa valutare l'integrità dell'artefatto e decidere se procedere o meno con esso.

Siamo in grado di valutare l’integrità di un manufatto in due modi. 

Uno è valutando il provenienza del manufatto.

Generando a Attestazione di provenienza, forniamo metadati utili (correttamente autenticati e non ripudiati) sull'artefatto. Negli esempi seguenti useremo SALE Xygeni (Software Attestations Layer for Trust), il componente per generare, registrare e verificare le attestazioni software.

Tamper_Proof_Builds
      - name: Building ...
        run: |
          # mvn will compile and create target/MyApp.war
          mvn clean package
             
      - name: Generating provenance
        run: |
              #!/usr/bin/env bash


              shopt -s expand_aliases
              alias salt=$PWD/salt_pro/xygeni_salt/salt
     
              echo " "
              echo "-----------"
              echo "Generating Provenance with CLI ..."
              salt at slsa \
                  --basedir ${GITHUB_WORKSPACE}/target \
            --key="${PRIVATE_KEY}" \
            --public-key=${GITHUB_WORKSPACE}/Test1_public.pem \  
            --key-password=${KEY_PASSWD} \
              --output-unsigned=${GITHUB_WORKSPACE}/cli_provenance_${PIPELINE}_unsigned.json \
                  --pipeline ${PIPELINE} --pretty-print \
                  --file ./MyApp.war      
             

Nel codice sopra, puoi vedere che c'è un passaggio che crea il file war e un secondo passaggio che genera il file Attestazione di provenienza. Per farlo, il pipeline utilizza la chiave privata e include anche la chiave pubblica nell'attestazione. 

Dietro le quinte, Xygeni sale Il comando memorizza l'attestazione in a libro mastro (noto anche come registro di attestazione, record nel nostro caso ma puoi usarne qualsiasi altro). Fatto questo, il consumatore pipeline può includere quello di Xygeni Motore di verifica verificare la provenienza del manufatto e valutare l'integrità del manufatto.

 - name: 'Verifying the attestation'
        run: |
          #!/usr/bin/bash


	    echo " "
          echo "-------"
          # Calculate sha256sum for the artifact
          SHA_SUM=$(sha256sum ./MyApp.war | cut -f1 -d ' ')


	    # Recover the attestation Id from the sha256sum
          ATT_ID=$(echo $(salt -q registry search --digest sha256:$SHA_SUM --format json) | jq -r .[-1].gitoidSha256)


          echo " "
          echo "-------"
          # Download the provenance attestation
          echo "Downloading the provenance attestation ..."
          salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json


          echo " "
          echo "-------"
          echo "Verifying provenance ..."
          salt verify \
              --basedir ${GITHUB_WORKSPACE} \
              --attestation=${GITHUB_WORKSPACE}/provenance_kk.signed.json \
              --public-key=${GITHUB_WORKSPACE}/Test1_public.pem \
              --file ./MyApp.war

Il processo di verifica valuta:

  • Migliori l'artefatto sha256sum è valido (cioè c'è un'attestazione su quel “soggetto”), e
  • Migliori l'attestazione sia correttamente autenticata (è stato generato utilizzando la chiave privata adeguata) 

Questo processo di verifica può quindi valutare che sia l'artefatto che l'attestazione siano validi.

Ma, come ricorderete, nel nostro caso l'artefatto è stato generato da un elemento “dannoso” pipeline (cioè non l'originale da un modificato pipeline). Poi bisogna andare avanti e verificare un altro aspetto: quello l'artefatto è stato generato dall'“originale” pipeline, nessun altro. 

Per fare ciò, includi semplicemente una semplice riga per verificare quella condizione, ad esempio:

   echo " "
          echo "-------"
          # Download the provenance attestation
          echo "Downloading the provenance attestation ..."
          salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json
          WFR=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json |base64 -d | jq -r .predicate.buildDefinition.internalParameters.environment.GITHUB_WORKFLOW_REF)
          echo $WFR | grep cicd_top10_3_salt\/.github\/workflows\/build.yml

Questo ulteriore controllo fallirà se l’artefatto non fosse stato generato dalla nostra “cassaforte” pipeline.

Se l'artefatto è stato generato dal nostro file originale pipeline (cicd_top10_3_salt/.github/workflows/build.yml), il comando grep avrà successo, altrimenti fallirà, interrompendo il pipeline e annullare qualsiasi ulteriore passaggio.

Il costruttore" pipeline è solo uno dei punti di manomissione da controllare ma, come accennato in precedenza, ce ne sono altri che dovremmo controllare.

Per esempio, cosa succede se il codice sorgente è stato manomesso dopo il checkout del repository e prima del comando build? In questo caso, il codice da costruire non è lo stesso memorizzato nel SCM. 

Controllare questo punto di manomissione è così semplice da controllare gli hash del materiale ad ogni passaggio.

SHA_ATT_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[0].predicate.materials[].digest[])
SHA_STEP_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[3].predicate.materials[0].digest[])

Conclusioni

In sintesi, a Attestazione del software è un'asserzione fatta su un pezzo di software, cioè una dichiarazione autenticata (metadati) su un artefatto software o una raccolta di artefatti software.

Le attestazioni software sono una generalizzazione della firma di artefatti/codici grezzi. L'attestazione è un documento firmato (in un determinato formato, tipicamente basato su JSON) che associa i metadati a un artefatto. Rappresentano prove che collegano input (materiali) e output (artefatti prodotti) in ogni fase di costruzione.

Le attestazioni forniscono una registrazione verificabile dei passaggi eseguiti per la creazione degli artefatti software finali, inclusi i materiali di input per ogni passaggio e i comandi di creazione eseguiti.

In conclusione, le attestazioni software sono un ottimo meccanismo per verificare molti aspetti diversi dell'integrità del nostro processo di creazione. 

Finita la serie? Non preoccuparti! Sentiti libero di tornare indietro a 'Avvelenato Pipeline Esecuzione (DPI)' o qualsiasi altro post che susciti nuovamente il tuo interesse!

Rimanete sintonizzati, approfondiremo le attestazioni software e build security in ulteriori post del blog. 

Avvelenato Pipeline Esecuzione (DPI)

Un tuffo profondo CI/CD Pipelines Vulnerabilità (I)​

Avvelenato indiretto Pipeline Esecuzione (I-PPE)

Un tuffo profondo CI/CD Pipelines Vulnerabilità (II)​

Avvelenamento di artefatti e iniezione di codice

Un tuffo profondo CI/CD Pipelines Vulnerabilità (III)​
sca-tools-software-strumenti-di-analisi-della-composizione
Dai priorità, risolvi e proteggi i rischi del tuo software
Prova gratuita 7-day
Nessuna carta di credito richiesta

Proteggi lo sviluppo e la consegna del tuo software

con la suite di prodotti Xygeni