Dalam catatan kami sebelum ini tentang CI/CD Pipelines, kami nampak cara menggodam CI/CD senario yang mungkin telah dilindungi.
Mari kita ingat kembali apa yang kita katakan dalam catatan sebelumnya: kami mulakan dengan beberapa pipeline yang terdedah kepada Keracunan Tidak Langsung Pipeline Pelaksanaan (I-PPE) dan, untuk memperbaikinya, kami memutuskan untuk membahagikannya pipeline kepada dua:
- Yang ke-1 pipeline (Binaan CI), selamat untuk D-PPE dan I-PPE, akan menyemak kod PR, membuat binaan dan menjana artifak
- Yang ke-2 pipeline (Test CI), juga selamat untuk D-PPE dan I-PPE akan menyemak kod Asas (untuk mengelakkan pengubahsuaian skrip shell) dan melaksanakan skrip asal terhadap artifak tersebut.
- Untuk menyegerakkan CI Ujian pipeline untuk dijalankan SELEPAS CI Binaan pipeline, kami gunakan aliran_jalan pencetus.
Kami menamakan ini sebagai Senario #3.

Walaupun, seperti yang telah kami nyatakan dalam catatan itu, terdapat penyelesaian lain, kami memutuskan untuk melaksanakan "penyelesaian" ini atas sebab-sebab pedagogi, supaya kami dapat menyelidiki lebih mendalam tentang kelemahan CI/CD pipelines.
Selepas itu, kami melihat cara menggodam senario ini dengan meracuni artifak. Inilah yang kami panggil Keracunan Artifak, iaitu keupayaan untuk mengubah suai (menggoda) pipeline logik dengan mengubah suai pipeline artifak.
Apakah masalah dengan pendekatan ini? Kami melihat bahawa masalah timbul apabila mana-mana pengguna "mencipta" yang baharu pipeline.
Jika pengguna membuka PR yang mengandungi yang baharu pipeline, GitHub akan melaksanakannya pipeline (memandangkan beberapa syarat, seperti yang kita lihat dalam jawatan).
Pengguna kemudiannya boleh mencipta yang baharu pipeline dengan nama yang sama seperti Build CI!! Ya, ia mengejutkan, tetapi GitHub membolehkan anda mencipta dua pipelines dengan nama yang sama!!
Apabila pengguna membuka PR dengan perubahan ini, baru" pipeline akan dilaksanakan (memuat naik artifak beracun) dan CI Deploy pipeline akan dilaksanakan selepas itu, mengakibatkan skrip shell yang "diubah suai" menulis ganti skrip shell "asal" yang terletak di pipeline ruang kerja. Jadi, "penyelesaian" ini tidak mengelakkan kerentanan I-PPE (seperti yang dapat kita lihat di bawah)

Apakah masalahnya? Sekurang-kurangnya, terdapat beberapa isu:
- Pertama, bagaimana untuk memastikan proses pembinaan tidak diganggu? Dalam senario ini, pengguna yang berniat jahat telah dapat mengubah suai proses binaan yang dimaksudkan dengan menggunakan pipeline untuk mencipta artifak beracun.
- Kedua, Bagaimanakah kita boleh menilai asal-usul sesuatu artifak?
Soalan-soalan ini membawa kita ke dalam pelukan Pengesahan Perisian domain!!
Pengesahan Perisian
An pengesahan adalah sekeping data mewakili bukti sesuatu peristiwa. Dalam dunia sebenar, kita biasanya memanggilnya Pensijilan.
Contohnya, apabila makmal menguji darah anda, data tentang ujian tersebut direkodkan dan diperakui. Keputusan ujian darah adalah disahkan dan dapat dikesan.

Lebih dekat dengan domain IT kita, anda boleh meneka apakah terjemahan proses ini kepada, sebagai contoh, proses kompilasi.

Maklumat tentang persekitaran dan alatan pelayan kompilasi, bahan (kod sumber) dan produk/artifak (kod binari) akan menjadi sebahagian daripada pengesahan tersebut.
Jelas sekali, pengesahan mesti dijana oleh saksi yang diberi kuasa (disahkan dan tidak boleh disangkal) untuk memberikan kredibiliti.
Kemungkinan besar, sebahagian daripada anda mungkin berfikir .. dan apakah itu perbezaan antara tandatangan dan pengesahan?
Tandatangan Kod dan Pengesahan
Pada tahap yang tinggi, seorang tanda tangan dicipta menggunakan pasangan kunci dan artifak. Pasangan kunci terdiri daripada kunci awam dan kunci persendirian.

Pengguna menandatangani artifak menggunakan kunci persendirian, dan orang lain kemudiannya boleh mengesahkan tandatangan menggunakan kunci awam. Kunci persendirian mesti dirahsiakan, tetapi kunci awam diedarkan secara meluas.
Tandatangan boleh digunakan untuk membuktikan bahawa pemegang kunci persendirian telah menggunakan kunci persendirian tersebut untuk menandatangani artifak tersebut.
Tandatangan jangan buktikan
- Pengguna niat untuk menandatangani artifak (mereka mungkin telah ditipu), atau
- Niat pengguna untuk membuat apa-apa tuntutan khusus tentang artifak tersebut
Dengan Pengakuan, daripada menandatangani artifak secara langsung, pengguna mencipta sejenis dokumen Bahawa menangkap niat mereka di belakang menandatangani artifak dan mana-mana tuntutan khusus dibuat sebagai sebahagian daripada tandatangan ini.
Rangka Kerja Pengesahan Dalam-Toto
Kerangka kerja yang paling biasa ialah Rangka Kerja Pengesahan dalam-toto
- mentakrifkan standard format untuk pengesahan yang mengikat subjek, artifak yang diterangkan, kepada metadata yang disahkan tentang artifak tersebut
- menyediakan satu set predikat yang telah ditakrifkan terlebih dahulu untuk menyampaikan metadata yang disahkan di seluruh dan merentasi rantaian bekalan perisian
Mari kita huraikan secara terperinci tentang format pengesahan.
An Pengesahan ialah dokumen yang ditandatangani secara digital yang mengandungi Kenyataan.
. Penyata merupakan lapisan tengah pengesahan, mengikatnya kepada sesuatu yang tertentu Tajuk dan mengenal pasti jenis-jenisnya dengan jelas Predikat:
- Tajuk: A rujukan selamat secara kriptografi kepada artifak (biasanya melalui hash), dan
- Predikat: satu set khusus tuntutan tentang artifak itu dirujuk sebagai Pernyataan. Dakwaan ini boleh digunakan untuk menyatakan (dan kemudian membuktikan) apa sahaja yang anda boleh fikirkan! Dakwaan ini boleh mewakili kelulusan manual, asal usul artifak, keputusan ujian automatik, jejak audit atau lebih lagi!
Apabila Pernyataan ini ditandatangani secara kriptografi, ia kemudiannya dirujuk sebagai Pengesahan

Dengan cara ini, sebagai contoh, Alice mencipta Pernyataan tentang artifak dan menandatanganinya menggunakan kunci persendiriannya, sekali gus mewujudkan Pengesahan.
- Bob kemudiannya boleh sahkan tandatangan dalam Pengesahan itu, membenarkannya untuk mempercayai dakwaan-dakwaan dalam.
Bob kemudiannya boleh menggunakan tuntutan tersebut untuk membuat keputusan sama ada untuk membenarkan artifak ini digunakan atau tidak.

Bolehkah Atestasi membantu menyelesaikan Keracunan Artifak?
Selepas pengenalan kepada Pengesahan ini, mari kita kembali kepada masalah kita. Bagaimanakah pengesahan dapat membantu kita menyelesaikan masalah kita, iaitu untuk mengelakkan keracunan artifak?
Pengguna yang berniat jahat itu berjaya mencipta artifak dengan memintas mekanisme "rasmi", iaitu dengan menggunakan pipeline untuk menghasilkan artifak tersebut.
Amat menakjubkan jika kita dapat membuktikan bahawa artifak yang dimuat turun telah dibina dengan perisian rasmi pipelines. Ini hanyalah satu contoh daripada apa yang boleh kita panggil "Titik Pengubahan", tetapi mungkin terdapat banyak lagi contoh yang lain.

Seperti yang anda dapat lihat dalam gambar di atas, titik gangguan adalah berbilang. Dengan cara ini, pengguna pipeline (Ujian CI dalam contoh kita) mesti menilai integriti proses pembinaan serta integriti artifak itu sendiri.
Dalam contoh kita, artifak beracun telah dicipta dengan memperkenalkan artifak baharu (beracun) pipeline yang mengganggu proses binaan. Tetapi pengguna yang berniat jahat itu mungkin boleh:
- ubah suai kod selepas diperiksa keluar dari SCM untuk menghasilkan binari berniat jahat
- gantikan binari kanan yang dihasilkan oleh kompilasi dengan mana-mana binari berniat jahat yang lain
- menjejaskan Daftar Artifak dan memuat naik artifak beracun yang dibina dengan cara lain
- dan lain-lain.
Seperti yang anda lihat, mungkin terdapat beberapa titik "gangguan".
Apa yang penting di sini? Sudah tentu untuk melindungi semua perkara "gangguan" tersebut. Tetapi, pada akhirnya, apa yang paling penting ialah bahawa "pengguna" artifak tersebut boleh menilai integriti artifak tersebut dan memutuskan sama ada untuk meneruskannya atau tidak.
Kita boleh menilai integriti artifak dalam dua cara.
Salah satunya adalah dengan menilai asal daripada artifak itu.
Dengan menjana Pengesahan Asal-usul, kami menyediakan metadata yang berguna (disahkan dengan betul dan tidak disangkal) tentang artifak tersebut. Dalam contoh-contoh berikut, kita akan menggunakan GARAM Xygeni (Lapisan Pengesahan Perisian untuk Kepercayaan), komponen untuk menjana, mendaftar dan mengesahkan pengesahan perisian.

- 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
Dalam kod di atas, anda dapat melihat terdapat langkah yang membina fail perang dan langkah kedua yang menjana Pengesahan Asal-usulUntuk melakukannya, pipeline menggunakan kunci persendirian dan juga memasukkan kunci awam dalam pengesahan.
Di sebalik tabir, Xygeni's garam arahan menyimpan pengesahan dalam a lejar (juga dikenali sebagai daftar pengesahan, rekod dalam kes kami tetapi anda boleh menggunakan yang lain). Setelah selesai, pengguna pipeline boleh merangkumi Xygeni Enjin Pengesahan untuk mengesahkan asal usul artifak dan menilai integriti artifak tersebut.
- 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
Proses pengesahan menilai:
- . artifak sha256sum adalah sah (iaitu terdapat pengesahan tentang "subjek" itu), dan
- . pengesahan disahkan dengan betul (ia telah dijana dengan menggunakan kunci persendirian yang mencukupi)
Proses pengesahan ini kemudiannya dapat menilai sama ada kedua-dua artifak dan pengesahan adalah sah.
Tetapi, seperti yang anda ingat, dalam kes kami, artifak itu dihasilkan oleh "berniat jahat" pipeline (iaitu bukan yang asal oleh pengubahsuaian pipeline). Kemudian kita mesti teruskan dan semak aspek lain: bahawa artifak itu telah dihasilkan oleh "asal" pipeline, bukan yang lain.
Untuk melakukannya, sertakan sahaja baris mudah untuk menyemak keadaan tersebut, contohnya:
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
Pemeriksaan tambahan ini akan gagal jika artifak tersebut tidak dijana oleh "peti besi" kami. pipeline.
Jika artifak itu dihasilkan oleh artifak asal kita pipeline (cicd_top10_3_salt/.github/workflows/build.yml), arahan grep akan berjaya, jika tidak, ia akan gagal, melanggar pipeline dan membatalkan sebarang langkah selanjutnya.
"Pembina" pipeline hanyalah satu perkara gangguan untuk diperiksa tetapi, seperti yang dinyatakan sebelum ini, terdapat beberapa perkara gangguan lain yang perlu kita periksa.
Sebagai contoh, bagaimana jika kod sumber telah diusik selepas pembayaran repo dan sebelum arahan binaan? Dalam kes ini, kod yang hendak dibina tidak sama seperti yang disimpan dalam SCM.
Untuk memeriksa titik gangguan ini adalah sangat mudah seperti menyemak hash bahan pada setiap langkah.
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[])
kesimpulan
Secara ringkasnya, sebuah Pengesahan Perisian merupakan penegasan yang dibuat tentang sesuatu perisian, iaitu pernyataan yang disahkan (metadata) tentang artifak perisian atau koleksi artifak perisian.
Pengesahan perisian merupakan generalisasi bagi penandatanganan artifak/kod mentah. Pengesahan tersebut merupakan dokumen yang ditandatangani (dalam format tertentu, biasanya berdasarkan JSON) yang mengaitkan metadata dengan artifak. Ia mewakili bukti yang menghubungkan input (bahan) dan output (artifak yang dihasilkan) pada setiap langkah binaan.
Pengesahan menyediakan rekod yang boleh disahkan tentang langkah-langkah yang dilakukan untuk membina artifak perisian akhir, termasuk bahan input untuk setiap langkah dan arahan binaan yang dijalankan.
Kesimpulannya, Pengesahan Perisian merupakan mekanisme yang hebat untuk menyemak pelbagai aspek integriti dalam proses binaan kami.
Dah habis siri ini? Jangan risau! Sila kembali ke 'Beracun Pipeline Pelaksanaan (PPE)' atau mana-mana catatan lain yang menarik minat anda sekali lagi!
Teruskan mengikuti perkembangan selanjutnya, kami akan mengkaji lebih lanjut tentang pengesahan perisian dan build security dalam catatan blog selanjutnya.







