Serangan supply chain poisoning sering memanfaatkan eksekusi binary langsung dari GitHub Release. Pola serangan mencakup pembajakan token akun developer, kompromi CI/CD build runner, hingga pembuatan repositori tiruan (typo-squatting) yang mendistribusikan malware executable berkedok rilis resmi software populer. Pola instalasi umum curl | bash tanpa verifikasi integritas mengeksekusi payload langsung ke sistem tanpa proteksi.

Mitigasi serangan ini membutuhkan penghentian eksekusi artefak berbasis kepercayaan implisit. Verifikasi hash release GitHub, penegakan integritas kriptografis, serta validasi identitas signer sebelum artefak bereksekusi di lingkungan lokal atau server CI/CD adalah kontrol teknis wajib.

Vektor Ancaman: Typosquatting dan Kompromi Release Asset

Penyerang mendistribusikan malware melalui dua vektor utama pada ekosistem GitHub Release:

  • Repositori Typosquatting: Penyerang membuat akun dan repositori dengan nama menyerupai proyek populer (misal, ripgrep vs rlpgrep) lalu mengunggah executable yang disusupi malware infostealer atau backdoor.
  • Release Asset Tampering: Aktor ancaman memperoleh akses write melalui token PAT yang bocor atau serangan CI/CD script-injection, lalu mengganti binary rilis yang sudah ada atau menyisipkan file tambahan tanpa mengubah kode sumber commit target.

Mengunduh file hanya berdasarkan URL rilis atau tag Git tidak menjamin keamanan artefak. Tag Git bersifat mutable dan aset rilis pada GitHub dapat diganti tanpa meninggalkan jejak mutasi pada Git tree.

Strict Hash Pinning pada Binary Installer

Pola instalasi berbasis shell script wajib menerapkan komparasi hash independen menggunakan SHA-256. Nilai hash target tidak boleh diunduh dari server atau tag rilis yang sama pada runtime, melainkan di-hardcode (pinned) ke dalam repositori atau konfigurasi deployment yang terkontrol.

#!/usr/bin/env bash
set -euo pipefail

TOOL_VERSION="v1.4.0"
EXPECTED_SHA256="a3f81e3a479b1d3d66f68c3479a864e2621cb036d0b30bb6329e46a788dc65b9"
DOWNLOAD_URL="https://github.com/example-org/secure-cli/releases/download/${TOOL_VERSION}/secure-cli-linux-amd64"
TARGET_BIN="/usr/local/bin/secure-cli"
TMP_FILE="/tmp/secure-cli-bin"

# Unduh binary langsung ke direktori sementara
curl -sSL "${DOWNLOAD_URL}" -o "${TMP_FILE}"

# Verifikasi hash SHA-256
ACTUAL_SHA256=$(sha256sum "${TMP_FILE}" | cut -d ' ' -f 1)

if [ "${ACTUAL_SHA256}" != "${EXPECTED_SHA256}" ]; then
  echo "ERROR: Checksum SHA-256 mismatch!" >&2
  echo "Diharapkan : ${EXPECTED_SHA256}" >&2
  echo "Ditemukan  : ${ACTUAL_SHA256}" >&2
  rm -f "${TMP_FILE}"
  exit 1
fi

chmod +x "${TMP_FILE}"
mv "${TMP_FILE}" "${TARGET_BIN}"
echo "Verifikasi sukses: binary valid dan terpasang."

Implementasi ini memblokir eksekusi binary yang diubah di storage GitHub rilis. Jika penyerang mengganti binary di release bucket, hash tidak cocok dan script langsung berhenti sebelum chmod +x dijalankan.

Verifikasi Kriptografis Berbasis Cosign dan SLSA Provenance

Verifikasi checksum mandiri tidak mendeteksi kompromi upstream saat penyerang mengubah file rilis sekaligus teks checksums.txt. Mekanisme cryptographically-signed via Cosign (Sigstore) memvalidasi keaslian (provenance) tanpa mengandalkan server PKI internal.

1. Validasi Tanda Tangan Binary dengan Cosign

Cosign memvalidasi bahwa binary dikompilasi oleh alur kerja GitHub Actions resmi dan ditandatangani oleh sertifikat OIDC repositori upstream, bukan buatan pihak ketiga.

# Unduh binary, file signature, dan sertifikat rilis
curl -sSL -O https://github.com/org/app/releases/download/v2.0.0/app-linux-amd64
curl -sSL -O https://github.com/org/app/releases/download/v2.0.0/app-linux-amd64.sig
curl -sSL -O https://github.com/org/app/releases/download/v2.0.0/app-linux-amd64.pem

# Validasi identitas signer dan issuer OIDC
cosign verify-blob app-linux-amd64 \
  --signature app-linux-amd64.sig \
  --certificate app-linux-amd64.pem \
  --certificate-identity "https://github.com/org/app/.github/workflows/release.yml@refs/tags/v2.0.0" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

Bila identitas certificate (SAN) berbeda dari alur kerja GitHub Actions resmi proyek tersebut, instruksi cosign mengembalikan return code non-zero dan membatalkan pipeline.

2. Verifikasi Dokumen SLSA Provenance

Jika pengembang menggunakan slsa-github-generator, aset rilis dilengkapi file attestations berformat in-toto (.intoto.jsonl). Gunakan slsa-verifier untuk memastikan binary dibuat murni dari sumber repositori dan tag Git yang valid:

slsa-verifier verify-artifact app-linux-amd64 \
  --provenance-path multiple.intoto.jsonl \
  --source-uri github.com/org/app \
  --source-tag v2.0.0

Otomatisasi Audit Integritas pada CI/CD Pipeline

Pencegahan di lingkungan runtime deployment (seperti GitHub Actions Runner) dilakukan dengan memvalidasi semua executable eksternal sebelum dieksekusi. Berikut contoh alur kerja GitHub Actions yang menolak instalasi dependensi binary yang tidak lolos validasi hash terdistribusi.

name: Secure Tool Installation
on: [push]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Source Code
        uses: actions/checkout@v4

      - name: Setup Tools with Checksum Verification
        run: |
          CLI_VERSION="0.18.2"
          CLI_URL="https://github.com/protocolbuffers/protobuf/releases/download/v${CLI_VERSION}/protoc-${CLI_VERSION}-linux-x86_64.zip"
          
          # Sumber hash wajib dibaca dari file versi yang dikontrol Git
          EXPECTED_HASH="d7d1ec34a04e578c74384a24285b064fb97bb1f5c6ea47913cfca844c856754d"
          
          curl -sSL "${CLI_URL}" -o protoc.zip
          echo "${EXPECTED_HASH}  protoc.zip" | sha256sum --check --strict
          
          unzip -q protoc.zip -d /usr/local/protoc
          echo "/usr/local/protoc/bin" >> $GITHUB_PATH

      - name: Run Build Process
        run: |
          protoc --version

Penggunaan sha256sum --check --strict memastikan bahwa jika hash berbeda sedikit pun, GitHub Action akan melempar fatal error dan menghentikan pipeline seketika, mencegah potensi exfiltrasi secrets CI.

Kesalahan Umum dan Batasan Teknis

Berikut sejumlah kesalahan implementasi yang merusak efektivitas verifikasi hash:

  • Mengunduh Checksum dari URL yang Sama Secara Dinamis: Menjalankan curl $URL/tool lalu menjalankan curl $URL/tool.sha256 tidak memberikan perlindungan jika repositori atau supply path-nya sudah disusupi. Hash harus disimpan secara independen.
  • Mengabaikan Return Code Subshell: Script Bash yang tidak menggunakan set -euo pipefail dapat melewatkan kegagalan validasi hash jika perintah parsing setelahnya bernilai sukses (exit code 0).
  • Mempercayai Branch Head: Mengunduh artefak rilis dengan tag dinamis seperti latest membuat hash pinning mustahil diterapkan secara deterministik. Selalu sematkan versi rilis immutable (misal v1.2.3).

Menerapkan strict hash pinning dan verifikasi cosign mengeliminasi ketergantungan pada reputasi repositori semata, melindungi runner CI/CD dan workstation teknisi dari injeksi binary berbahaya.