diracunipipeline-pelaksanaan-II

Menyelam Dalam CI/CD PipelineKerentanan (II): Keracunan Tidak Langsung Pipeline Pelaksanaan (I-PPE)

Dalam catatan kami sebelum ini, kami telah melihat cara untuk mengesan dan melindungi daripada Keracunan Langsung Pipeline Pelaksanaan (D-PPE). Kami juga melihat cara mengesan kerentanan tersebut menggunakan Pengimbas Xygeni, serta beberapa mekanisme perlindungan. 

 Beracun Pipeline Pelaksanaan (PPE) dihasilkan apabila penyerang boleh mengubah suai pipeline logik dalam salah satu daripada dua cara:

  • Dengan mengubah suai fail konfigurasi CI (yang pipeline) -> PPE Langsung (D-PPE)
  • Dengan mengubah suai fail yang dirujuk oleh pipeline (contohnya: skrip yang dirujuk dari dalam pipeline fail konfigurasi) -> PPE Tidak Langsung (I-PPE)
pp2

Dalam catatan ini, kita akan mendalami PPE Tidak Langsung. Tetapi, sebelum itu, dan sebagai pelengkap kepada catatan saya sebelum ini, mari kita lihat dahulu bagaimana GitHub mengurus pelaksanaan pipelines dan apakah mekanisme perlindungan terhadap D-PPE.

Bagaimanakah GitHub melindungi pelaksanaan pipelinedatangnya daripada PR?

Bagaimanakah GitHub berfungsi mengenai pelaksanaan yang diubah suai pipelines?

Diubahsuai pipelines boleh datang daripada Tolakan atau Pull Requests (PR). Sebagai amalan terbaik utama, adalah sangat disyorkan untuk mengelakkan sebarang "tolak" langsung ke cawangan yang dilindungi dan menggunakan Pull Requests sebagai mekanisme untuk menguatkuasakan beberapa semakan sebelum menerima sebarang kod yang disumbangkan. 

Pull Requests mungkin datang dari dua sumber yang berbeza:

  • PR yang datang dari garpu
  • PR yang datang dari cawangan

PR daripada garpu boleh datang sama ada dari awam or swasta repositori.

Memandangkan kita berurusan dengan PPE (Keracunan Pipeline Pelaksanaan), perkara utama kami bukanlah "penerimaan" PR tetapi pelaksanaan yang diubah suai pipeline semasa proses penerimaan/kelulusan PR. Teras serangan PPE, terdapat pelaksanaan yang tidak disengajakan bagi tindakan yang diubah suai yang "berniat jahat" pipeline. 

Dalam beberapa perkataan, Keracunan Pipeline Pelaksanaan (PPE) dihasilkan apabila penyerang boleh mengubah suai pipeline logik.

Terdapat dua varian:

  • PPE langsung (D-PPE): Dalam senario D-PPE, penyerang mengubah suai fail konfigurasi CI dalam repositori yang mereka boleh akses kepada, sama ada dengan menolak perubahan terus ke cawangan jauh yang tidak dilindungi pada repo, atau dengan menghantar PR dengan perubahan daripada cawangan atau fork. Sejak CI pipeline pelaksanaan ditakrifkan oleh arahan dalam fail konfigurasi CI yang diubah suai, arahan berniat jahat penyerang akhirnya berjalan dalam nod binaan sebaik sahaja binaan pipeline dicetuskan.
  • PPE tidak langsung (I-PPE): Dalam kes tertentu, kemungkinan D-PPE tidak tersedia kepada musuh yang mempunyai akses kepada SCM repositori (cth. jika pipeline dikonfigurasikan untuk menarik fail konfigurasi CI daripada cawangan berasingan yang dilindungi dalam repositori yang sama). Dalam senario sedemikian, daripada meracuni pipeline sendiri, penyerang menyuntik kod berniat jahat ke dalam fail yang dirujuk oleh pipeline (contohnya: skrip yang dirujuk dari dalam pipeline fail konfigurasi)

Dalam kedua-dua kes, GitHub akan melaksanakan yang diubah suai pipeline tanpa memerlukan semakan atau kelulusan terdahulu.

PR dari fork pada awam repo

GitHub membenarkan konfigurasi tingkah laku semasa memproses PR yang datang daripada fork dalam repo awam.

Apabila PR datang dari fork, GitHub sentiasa memaksa beberapa tahap "kelulusan" sebelum melaksanakannya pipeline berkaitan dengan PRTahap kelulusan ini bertukar daripada kelulusan yang lemah kepada kelulusan yang ketat.

At Tahap organisasi (Org>>Tetapan>>Tindakan>>Umum), anda boleh memutuskan antara beberapa pilihan "kelulusan":

ppe3

Yang paling ketat adalah yang terakhir (“Memerlukan kelulusan daripada semua rakan usaha sama luar"") kerana GitHub akan sentiasa memerlukan kelulusan apabila PR datang daripada fork daripada kolaborator luar. 

Tetapi walaupun dalam kes yang ketat ini, terdapat perbezaan antara kolaborator dengan kebenaran baca dan tulis.

  • Apabila PR datang daripada membaca pengguna, yang pelaksanaan pipeline DIHENTIKAN sehingga terdapat kelulusan perubahan. Jika kelulusan itu ok, maka perubahan yang diubah suai pipeline dilaksanakan. 
  • Apabila PR datang daripada menulis pengguna, yang kelulusan tidak diperlukan dan yang diubah suai pipeline sentiasa dilaksanakan!! 
pp4

Kesimpulannya, PR yang datang daripada fork pada repositori awam dilindungi sedikit daripada PPE. Terdapat beberapa perlindungan terhadap pengguna luaran (baca), tetapi tiada apa yang berkaitan dengan pengguna dalaman (tulis).

Bagaimana pula PR datang daripada fork daripada repo persendirian?

PR dari fork pada swasta repo

Dalam senario ini, GitHub menyediakan beberapa tetapan konfigurasi yang berguna.

ppe9

Tetapan di atas boleh dikonfigurasikan sama ada pada organ atau sekurang- repo peringkat.

Bila tiada pilihan ditanda, GitHub akan minta kelulusan dan ia tidak akan melaksanakan yang diubah suai pipelineIni konfigurasi yang paling selamat!!

. konfigurasi paling tidak selamat adalah apabila "Jalankan aliran kerja daripada fork pull request"diperiksaDalam kes ini, sama untuk pengguna baca dan tulis, Github akan melaksanakan secara automatik yang diubah suai pipeline!! Dan situasi ini boleh jadi sekata teruk jika "Hantar token tulis ke aliran kerja daripada fork pull requests"Dan"Hantar rahsia dan pembolehubah ke aliran kerja daripada fork pull requests"ditanda. Jangan lakukan ini melainkan jika dibenarkan dengan jelas!!

Sekiranya "Memerlukan kelulusan untuk fork pull request Aliran kerja"ditanda, situasi di atas agak dipertingkatkan: GitHub akan meminta kelulusan dan tidak melaksanakan yang diubah suai pipeline untuk pengguna baca, tetapi ia masih akan melaksanakannya untuk pengguna tulis.

ppe6

Garpu kelihatan, bagaimana pula PR yang datang dari cawangan?

PR daripada cawangan

Untuk melindungi senario ini, anda mesti bergantung pada Peraturan Perlindungan Cawangan. 

Pada peringkat repo, anda boleh mencipta peraturan perlindungan cawangan untuk mana-mana cawangan. Peraturan ini menambah beberapa kekangan kepada pengubahsuaian cawangan yang dilindungi.

Walaupun anda mengkonfigurasi peraturan kepada "Memerlukan a pull request sebelum penggabungan"Dan"Memerlukan kelulusan", yang diubah suai pipeline akan dilaksanakan secara automatik semasa penciptaan PR"Kelulusan" hanya akan terpakai kepada tindakan penggabungan.

ppe7

Bagaimana pula dengan Keracunan Tidak Langsung Pipeline Pelaksanaan

Seperti yang telah kita lihat di atas, D-PPE boleh dikurangkan dengan menggunakan sasaran_permintaan_tarik, Tetapi ia tidak terpakai kepada I-PPE.

Jika anda menggunakan pull_request_target, pembayaran lalai akan menjadi kod asas. Tetapi jika anda ingin mengesahkan beberapa pemeriksaan pada kod yang disumbangkan (kod PR), anda perlu menyemak kod PR secara eksplisit. Oleh itu, jika kod PR telah mengubah suai mana-mana skrip shell yang dipanggil oleh pipeline, "pangkalan" (selamat) pipeline akan memanggil skrip shell "diubah suai" → PPE Tidak Langsung!!

Penyelesaian untuk ini sedikit lebih rumit (tiada peluru ajaib seperti pull_request_target). 

Kami pipeline kini selamat untuk D-PPE kerana kita menggunakan pull_request_target. Tetapi ia masih terdedah kepada I-PPE. 

Dalam contoh ujian kami, kami perlu menyemak kod PR pada asasnya untuk membuat binaan, tetapi ujian dilaksanakan pada artifak yang dihasilkan oleh binaan. 

Jadi .. mengapa tidak menyemak kedua-dua pangkalan kod? 

  • Semak kod PR kerana kod yang disumbangkan itulah yang ingin kita bina dan uji
  • Kod Asas Semak untuk menjalankan versi asal pipeline dan skrip bina/ujian 

Ini mungkin dilakukan oleh menyemak pangkalan kod tersebut ke folder yang berbeza: kod asas mungkin disemak ke folder root, dan PR ke folder lain. Dalam kes ini, kita akan melaksanakan skrip binaan dan ujian daripada folder root terhadap kod yang diletakkan ke dalam folder baharu.

Ini penyelesaian yang mudah, sudah tentu!! Tetapi, untuk tujuan pembelajaran saya ingin memperkenalkan varian yang agak menarik (…) 

GitHub aliran_jalan peristiwa pencetus

Selain sasaran_permintaan_tarik, GitHub menyediakan satu lagi peristiwa pencetus: aliran_jalanAcara ini membolehkan pelaksanaan suatu pipeline dikondisikan kepada yang lain pipelinepelaksanaan. 

aliran_jalan dan sasaran_permintaan_tarik pencetus adalah serupa dalam satu aspek: kedua-duanya akan dilaksanakan dalam mod istimewa dan, walaupun terdapat pengubahsuaian PR, asasnya pipeline akan dihukum mati!! 

Mari kita lihat keadaan semasa kita pipeline:

				
					name: PR TARGET CI


on:
  pull_request_target:
    branches: [ main ]


env:
  MY_SECRET: ${{ secrets.MY_SECRET }}
 
jobs:
  prt_build_test_and_merge:
    runs-on: ubuntu-latest


    steps:
      # checkout PR code
      - name: Checkout repository
        uses: actions/checkout@v4
        with:


          # This is to get the PR code instead of the repo code
          ref: ${{ github.event.pull_request.head.sha }}


      # Simulation of a compilation
      - name: Building ...
        run: |
          mkdir ./bin
          touch ./bin/mybin.exe
          ls -lR
     
      # Simulation of running tests
      - name: Running tests ...
        id : run_tests
        run: |
          echo Running tests..
          chmod +x runtests.sh
          ./runtests.sh 
          echo Tests executed.
         
      #
      # Let’s omit the check conditions at this moment …
      #
      - name: pr_check_conditions_to_merge
        [...]
				
			

Bahagian binaan selamat untuk D-PPE, tetapi bahagian ujian masih terdedah kepada I-PPE.

. pipeline sendiri selamat untuk D-PPE kerana sasaran_permintaan_tarik pencetus. Tetapi langkah ujian masih terdedah kepada I-PPE kerana menggunakan skrip shell luaran.

Mengelakkan I-PPE 

Tujuan perkara di atas pipeline adalah untuk membina dan menguji kod yang disumbangkan, selamat untuk PPE. 

Jadi .. Mengapa tidak bahagikan pipeline menjadi dua? Satu untuk pembinaan dan satu lagi untuk pengujian..

  • Yang ke-1 pipeline (Bina CI) akan semak kod PR (untuk membinanya), buat binaan dan jana artifak.
  • Yang ke-2 pipeline (Ujian CI) akan semak kod Asas (untuk mengelakkan pengubahsuaian skrip shell) dan laksanakan skrip asal terhadap artifak tersebut. 
  • Untuk menyegerakkan CI Ujian pipeline untuk dijalankan SELEPAS CI Binaan pipeline, kita akan menggunakan aliran_jalan pencetus. 
ppe8

Dengan cara ini:

  • pipeline Bina CI is selamat kepada kedua-duanya D-PPE (disebabkan oleh sasaran_permintaan_tarik) dan I-PPE (kerana ia tidak lagi melaksanakan skrip shell).
  • pipeline Ujian CI juga selamat kepada kedua-duanya D-PPE (disebabkan oleh aliran_jalan) dan I-PPE (kerana ia menyemak kod asas untuk mendapatkan skrip shell asal) 

Mari kita lihat kod kedua-duanya pipelinemengikut pengubahsuaian ini …

1st pipeline (Bina CI):

				
					name: Build CI


on:
  pull_request_target:
    branches: [ main ]


env:
  MY_SECRET: ${{ secrets.MY_SECRET }}
  GITHUB_PAT: ${{ secrets.GH_PAT }}
 
jobs:
               
  prt_build_and_upload:
    runs-on: ubuntu-latest
    steps:
      - name: Checking out PR code
        uses: actions/checkout@v4
        if: ${{ github.event_name == 'pull_request_target' }}
        with:
          # This is to get the PR code instead of the repo code
          ref: ${{ github.event.pull_request.head.sha }}


      - name: Building ...
        run: |
          mkdir ./bin
          touch ./bin/mybin.exe
	    # Save some PR info for later use by the 2nd pipeline
          echo "${{github.event.pull_request.title}}" > ./bin/PR_TITLE.txt
          echo "${{github.event.number}}" > ./bin/PR_ID.txt
 
	# Upload the binary as a pipeline artifact
      - name: Archive building artifacts
        uses: actions/upload-artifact@v3
        with:
          name: archive-bin
          path: |
            bin
				
			

2nd pipeline (Ujian CI):

				
					ame: Test CI


on:
  workflow_run:
    workflows: [ 'PR TARGET CI' ]
    types: [completed]
   
env:
  MY_SECRET: ${{ secrets.MY_SECRET }}
  GITHUB_PAT: ${{ secrets.GH_PAT }}




jobs:
  deploy:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    steps:
 


      # By default, checks out base code (not PR code)
      - name: Checkout repository
        uses: actions/checkout@v4


	# Download the artifact
      - name: 'Download artifact'
        uses: actions/github-script@v6
        with:
          script: |
            let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: context.payload.workflow_run.id,
            });
            let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
              return artifact.name == "archive-bin"
            })[0];
            let download = await github.rest.actions.downloadArtifact({
               owner: context.repo.owner,
               repo: context.repo.repo,
               artifact_id: matchArtifact.id,
               archive_format: 'zip',
            });
            let fs = require('fs');
            fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/myartifact.zip`, Buffer.from(download.data));


	# Unzip the artifact
      - name: 'Unzip artifact'
        run: |
          unzip -o myartifact.zip


      # Runs tests
      - name: Running tests ...
        id : run_tests
        run: |
          echo Running tests..
          chmod +x runtests.sh
          ./runtests.sh
          echo Tests executed.


#
      # Let’s omit the check conditions at this moment …
      #
      - name: pr_check_conditions_to_merge
        [...]

				
			

Wah… penyelesaian yang bagus!! Tapi ….. Adakah kita selamat? Saya khuatir tidak 😭

Sesungguhnya, kami telah memperkenalkan kelemahan baharu!! Yang mana satu? Ini akan menjadi subjek catatan kami yang seterusnya 🙂 … Nantikan perkembangan selanjutnya!! 

PS: Maaf, saya tak boleh diam 🤐 ..Pernahkah anda dengar tentang Keracunan Artifak ? 😂

Keracunan Artifak dan Suntikan Kod

Menyelam Dalam CI/CD PipelineKerentanan (III)​

Melindungi daripada Keracunan Artifak melalui Pengesahan Perisian

Menyelam Dalam CI/CD PipelineKerentanan (IV)

Beracun Pipeline Pelaksanaan (PPE)

Menyelam Dalam CI/CD PipelineKerentanan (I)​
alat-analisis-komposisi-perisian-alat-sca
Utamakan, pulihkan dan lindungi risiko perisian anda
Dapatkan Akaun Percuma anda.
Tiada kad kredit yang diperlukan.

Lindungi pembangunan dan penghantaran perisian anda

dengan Suit Produk Xygeni