Membangun browser kustom berbasis engine besar seperti Chromium atau Gecko membutuhkan kontrol penuh atas alur kompilasi, terutama untuk kebutuhan privasi tinggi. Pengaturan manual rentan terhadap konfigurasi telemetri yang terlewat atau dependensi pihak ketiga yang menghubungi endpoint eksternal tanpa izin. Pipeline CI/CD mandiri memastikan setiap rilis melewati stripping telemetri, analisis statis, pengujian isolasi jaringan, dan verifikasi integritas biner secara otomatis.

Arsitektur Pipeline dan Strip-Down Kompilasi

Chromium mengandalkan tool build gn (Generate Ninja) dan ninja. Hardening privasi dimulai pada level kompilasi melalui berkas konfigurasi argumen (args.gn). Mengubah argumen ini menonaktifkan integrasi Google Services, crash reporting, pelaporan metrik, dan fitur pelacakan lainnya langsung di tingkat source tree.

Konfigurasi args.gn Anti-Telemetri

Berikut adalah subset parameter args.gn esensial untuk memangkas layanan pelacakan dan analitik pada engine Chromium:

is_debug = false
dcheck_always_on = false
is_official_build = true
symbol_level = 0

# Strip Google Services & SafeBrowsing
enable_google_now = false
google_api_key = ""
google_default_client_id = ""
google_default_client_secret = ""
safe_browsing_mode = 0

# Disable Crash Reporting & Telemetry
enable_reporting = false
enable_crash_reporter = false
build_with_tflite_lib = false

# Media & Codec stripping
enable_widevine = false
proprietary_codecs = false

# Network & Cloud integrators
enable_remoting = false
enable_service_discovery = false
use_cups = false

Argumen safe_browsing_mode = 0 dan pengosongan API key memutus koneksi fallback ke server upstream saat browser dijalankan pertama kali. Menonaktifkan crash reporter mencegah memory dump berisi artefak pengguna dikirim ke endpoint publik saat terjadi segmentation fault.

Deteksi Outbound Call Menggunakan Static Analysis

Penyisipan dependensi atau modifikasi modul dapat memicu panggilan jaringan yang tidak terdaftar. Pipeline CI harus menjalankan static code scanning untuk memeriksa string URL eksternal, domain hardcoded, serta implementasi interface jaringan seperti network::SimpleURLLoader sebelum build Ninja dimulai.

Skrip validasi cepat dapat diintegrasikan sebagai check step:

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

SRC_DIR="src/chrome"
FORBIDDEN_DOMAINS=(
  "google.com"
  "googleapis.com"
  "1e100.net"
  "gvt1.com"
  "crashlytics.com"
)

EXIT_CODE=0

for domain in "${FORBIDDEN_DOMAINS[@]}"; do
  echo "Checking for occurrences of: ${domain}"
  # Exclude test files and known localized mock domains
  MATCHES=$(grep -rnw "${SRC_DIR}" --exclude-dir=tests --exclude="*.md" -e "${domain}" || true)
  if [[ -n "${MATCHES}" ]]; then
    echo "[VIOLATION] Found hardcoded domain: ${domain}"
    echo "${MATCHES}" | head -n 10
    EXIT_CODE=1
  fi
done

exit ${EXIT_CODE}

Jika verifikasi gagal, runner CI menghentikan pipeline sebelum sumber daya komputasi terbuang untuk kompilasi biner.

Workflow CI Lengkap: Dari Kompilasi hingga Pengujian Headless

Kompilasi Chromium membutuhkan spesifikasi mesin tinggi (rekomendasi minimal 32 core CPU dan 64 GB RAM dengan disk swap yang memadai). Cache direktori output menggunakan ccache atau distributed compiler seperti sccache krusial untuk menjaga runtime pipeline tetap rasional.

Contoh pipeline menggunakan GitHub Actions atau GitLab CI Runner mandiri (Linux Ubuntu bare-metal runner):

name: Hardened Browser CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  audit-and-build:
    runs-on: [self-hosted, linux, high-perf]
    steps:
      - name: Checkout Source Code
        uses: actions/checkout@v4

      - name: Static Security Scan
        run: |
          chmod +x ./scripts/check-hardcoded-domains.sh
          ./scripts/check-hardcoded-domains.sh

      - name: Configure GN Args
        run: |
          mkdir -p out/HardenedRelease
          cp build/privacy_args.gn out/HardenedRelease/args.gn
          gn gen out/HardenedRelease

      - name: Build Binary (Ninja)
        run: |
          ninja -C out/HardenedRelease chrome

      - name: Headless Network Leak Test
        run: |
          # Start local traffic monitor (dumpcap/tcpdump)
          sudo tcpdump -i any -n "tcp or udp" -w /tmp/run_traffic.pcap &
          TCPDUMP_PID=$!
          sleep 2

          # Run binary in headless mode for 15 seconds
          ./out/HardenedRelease/chrome \
            --headless \
            --disable-gpu \
            --remote-debugging-port=9222 \
            --user-data-dir=$(mktemp -d) &
          CHROME_PID=$!
          
          sleep 15
          kill ${CHROME_PID} || true
          sleep 2
          sudo kill ${TCPDUMP_PID} || true

          # Assert no external traffic outside localhost
          PACKET_COUNT=$(tcpdump -nr /tmp/run_traffic.pcap "not host 127.0.0.1 and not ip6 ::1" 2>/dev/null | wc -l)
          if [ "${PACKET_COUNT}" -gt 0 ]; then
            echo "[FAIL] Unintended outbound traffic detected! Packet count: ${PACKET_COUNT}"
            tcpdump -nr /tmp/run_traffic.pcap "not host 127.0.0.1 and not ip6 ::1"
            exit 1
          fi
          echo "[PASS] Zero unauthorized outbound requests detected."

      - name: Generate SBOM and Checksums
        if: startsWith(github.ref, 'refs/tags/')
        run: |
          # Generate SBOM using syft
          curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
          syft ./out/HardenedRelease/chrome -o spdx-json=sbom.spdx.json

          # Generate SHA-256 and SHA-512 Checksums
          cd out/HardenedRelease/
          sha256sum chrome > chrome.sha256
          sha512sum chrome > chrome.sha512

      - name: Upload Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: hardened-browser-dist
          path: |
            out/HardenedRelease/chrome
            out/HardenedRelease/chrome.sha256
            out/HardenedRelease/chrome.sha512
            sbom.spdx.json

Pengujian Headless untuk Kebocoran Jaringan (Network Leak)

Pengujian biner secara interaktif tidak efisien di CI. Flag --headless dikombinasikan dengan capture paket lokal (menggunakan tcpdump atau script wrapper tshark) bertindak sebagai assertion layer terakhir.

Jika browser yang baru dikompilasi mencoba resolve DNS ke server eksternal, mengecek update komponen (CRLSet), atau mengirim sinyal SafeBrowsing, traffic capture mendeteksinya. Pipeline secara deterministik menandai build tersebut gagal (red build) tanpa mengekspos paket rilis ke production.

Rantai Pasok: Generasi SBOM dan Integritas Rilis

Browser kustom rentan terhadap kerentanan upstream di sub-komponen pihak ketiga (misalnya: HarfBuzz, ICU, v8, libpng). Integrasi SBOM (Software Bill of Materials) menggunakan format standar industri (seperti SPDX atau CycloneDX) memungkinkan audit downstream mengetahui daftar dependensi yang dikompilasi ke dalam biner.

  • SBOM Generation: Pipeline mengekstrak metadata paket menggunakan scanner biner (misal: Anchore Syft) untuk mencatat semua pustaka statis.
  • Checksum Verification: Biner final di-hash menggunakan algoritma SHA-256 dan SHA-512 sebelum distribusi. Klien atau instalasi otomatis memverifikasi digest biner guna mencegah tampering selama transmisi artefak.
  • Provenance: Artefak ditandatangani secara kriptografis menggunakan tool seperti Cosign untuk memastikan bahwa biner benar-benar berasal dari workflow CI resmi tanpa modifikasi pihak penengah.