Secret leak itu nggak selalu bentuknya file .env yang nggak sengaja ke-push ke GitHub. Kadang secret sudah bersih dari repo, tapi ikut kebawa ke artifact final: bundle JavaScript, container image, firmware, zip release, atau static asset yang akhirnya dikirim ke user.
Artikel ini membahas pelajaran praktis dari write-up “My security camera shipped a GitHub admin token in its login page”. Intinya sederhana: source code bukan satu-satunya tempat yang perlu diaudit. Kalau pipeline build lu menyuntikkan environment variable secara sembarangan, credential internal bisa masuk ke file final dan blast radius-nya bisa jauh lebih besar dari satu device.
Gua nggak akan bahas cara eksploitasi atau detail token. Fokusnya adalah checklist defensif buat developer: apa yang perlu dicek sebelum release, kenapa static asset bisa berbahaya, dan gimana bikin proses build yang lebih aman tanpa harus jadi tim security besar.
Kasusnya: token GitHub masuk ke firmware kamera
Dalam write-up tersebut, penulis membongkar firmware kamera Hanwha Vision yang tersedia publik. Setelah root filesystem bisa dibaca, penulis menjalankan tool pencari secret dan menemukan token GitHub yang muncul berkali-kali di file hasil build.
Bagian yang bikin kasus ini menarik buat developer web modern: token itu diduga ikut masuk karena UI kamera dibangun dengan Vite, lalu salah satu variable di bundle berisi environment build yang terlalu luas. Dengan kata lain, masalahnya bukan cuma “ada developer lupa hapus secret”. Masalahnya bisa berasal dari cara pipeline build memperlakukan environment variable.
Menurut write-up itu, token tersebut punya privilege admin ke banyak repository di organisasi GitHub terkait. Penulis juga menulis kemungkinan token tersebut bisa terkirim lewat admin UI kamera, walaupun bagian ini perlu dibaca hati-hati karena status remediation dan detail vendor response belum sepenuhnya jelas dari sumber resmi.
Pelajarannya tetap kuat: firmware dan static asset bukan file mati. Itu software supply chain yang bisa membawa credential dari CI/CD ke device edge.
Definisi singkat: artifact final itu apa?
Artifact final adalah output yang benar-benar lu ship ke user, server, device, atau registry. Contohnya:
- bundle JavaScript hasil
npm run build, - Docker image yang dipush ke registry,
- firmware perangkat IoT,
- file installer desktop,
- zip release di GitHub Releases,
- static asset di CDN,
- log build dan source map yang ikut kebuka publik.
Banyak tim sudah mulai sadar soal secret di repo. Tapi artifact final sering lolos dari perhatian karena dianggap “hasil build doang”. Padahal dari sisi attacker, artifact final justru menarik karena sering bisa diunduh tanpa akses repo internal.
Kenapa secret bisa masuk ke static asset?
Di frontend modern, environment variable sering dipakai buat konfigurasi build. Masalah muncul saat boundary antara variable publik dan secret internal nggak jelas.
Contoh aman: frontend butuh URL API publik atau feature flag non-sensitif. Contoh bahaya: token GitHub, token npm, credential cloud, private endpoint internal, atau metadata CI ikut terbaca oleh bundler lalu ditanam ke file JavaScript final.
Framework dan bundler biasanya punya konvensi prefix agar hanya variable tertentu yang boleh masuk ke client bundle. Vite, misalnya, punya konsep environment variable yang diekspos ke client lewat prefix tertentu. Tapi kalau aplikasi atau dependency mengambil process.env terlalu luas, atau pipeline menyuntikkan environment CI penuh, boundary itu bisa rusak.
Ini alasan gua selalu nganggep build step sebagai security boundary, bukan sekadar step teknis. Build bukan cuma mengubah TypeScript jadi JavaScript. Build juga memilih data apa yang akhirnya dibawa ke dunia luar.
Secret scanning jangan berhenti di repository
GitHub Secret Scanning membantu menemukan token, key, dan credential yang masuk ke repository. GitHub juga punya push protection dan validity checks untuk beberapa tipe secret agar kebocoran bisa dicegah atau diprioritaskan lebih cepat.
Itu penting, tapi belum cukup kalau secret baru muncul setelah proses build. Source code bisa bersih, tapi artifact final tetap bocor karena environment CI, plugin build, source map, atau script packaging.
Jadi mindset-nya perlu naik satu level: jangan cuma scan source. Scan juga output.
Checklist sebelum ship artifact final
Kalau lu developer solo, indie hacker, atau tim kecil, ini checklist yang bisa langsung dipakai minggu ini:
- Scan folder build. Jalankan secret scanner ke
dist/,build/, atau folder output sebelum deploy. - Scan container image. Jangan cuma scan Dockerfile. Scan image final karena layer lama, cache, dan file sementara bisa ikut kebawa.
- Cek source map. Kalau source map publik, pastikan isinya nggak membuka endpoint internal, komentar sensitif, atau variable build.
- Batasi environment variable di CI. Jangan kasih semua secret ke semua job. Job build frontend nggak perlu token admin organisasi.
- Pakai token scope minimum. Token buat install dependency seharusnya tidak punya admin access ke banyak repo.
- Rotate secret setelah incident kecil. Kalau secret pernah masuk artifact publik, anggap bocor. Jangan debat terlalu lama.
- Audit dependency build plugin. Plugin bundler, script postinstall, dan tool release bisa membaca environment lu.
- Simpan allowlist variable publik. Lebih aman eksplisit memilih variable yang boleh masuk bundle daripada membawa semua environment.
Versi praktis buat proyek frontend
Untuk aplikasi frontend, gua akan mulai dari aturan sederhana: semua variable yang masuk browser harus dianggap publik. Kalau user bisa buka DevTools, download JS, atau lihat network request, berarti nilai itu bukan secret.
Checklist frontend yang lebih spesifik:
- pisahkan file
.envserver dan client, - pakai prefix publik hanya untuk nilai yang memang boleh dilihat user,
- jangan pernah taruh token GitHub, token cloud, atau API key admin di variable client,
- review hasil bundle dengan pencarian kata seperti
token,secret,github,npm, dan nama service internal, - jangan expose source map production kalau belum punya alasan jelas,
- pastikan CI job build frontend tidak mewarisi environment secret dari job deploy backend.
Ini bukan paranoia. Ini hygiene. Sama seperti lu nggak akan commit password database ke repo, lu juga nggak seharusnya mengirim credential itu ke bundle final.
Kenapa ini relevan buat IoT dan device edge?
Kamera keamanan, router, NAS, printer, dan device kantor kecil sekarang makin mirip server mini. Mereka punya Linux, web UI, update firmware, dependency, telemetry, dan kadang fitur AI lokal.
Masalahnya, banyak orang masih memperlakukan device edge sebagai hardware biasa. Padahal kalau firmware membawa credential global, risiko yang muncul bisa lompat dari “satu kamera bermasalah” menjadi “akses ke repo, package, atau sistem internal ikut terancam”.
Ini juga alasan kenapa supply chain security nggak bisa cuma hidup di laptop developer. Ia harus ikut masuk ke proses release, firmware packaging, registry, dan update channel.
Takeaway buat developer
- Repo bersih belum tentu artifact final bersih.
- Environment variable di CI adalah data sensitif, bukan kantong konfigurasi bebas.
- Static asset bisa membawa credential kalau build step salah desain.
- Token scope kecil mengurangi ledakan risiko saat ada leak.
- Secret scanning paling berguna kalau dipasang sebelum dan sesudah build.
Menurut gua, ini tipe security lesson yang penting karena nggak butuh teori rumit. Lu bisa buka proyek lu hari ini, lihat pipeline build, dan tanya: “Artifact final gua sudah pernah discan belum?” Kalau jawabannya belum, itu task kecil yang worth masuk backlog.
FAQ singkat
Apakah semua firmware kamera Hanwha rentan?
Gua nggak akan klaim sejauh itu. Sumber utama adalah write-up individual yang membahas temuan pada firmware/model tertentu. Artikel ini mengambil pelajaran proses: jangan ship secret di artifact final.
Kalau repo sudah pakai GitHub Secret Scanning, apakah cukup?
Belum tentu. Secret scanning di repo penting, tapi secret bisa muncul setelah build. Scan juga folder output, container image, firmware, dan release package.
Apakah API key frontend selalu salah?
Tergantung. Key publik dengan scope terbatas dan rate limit bisa wajar. Yang salah adalah mengirim credential high-privilege seperti token admin, token cloud, atau secret backend ke browser/device.
Apa langkah pertama yang paling murah?
Mulai dari scan dist/ atau Docker image final, lalu audit environment variable yang tersedia di job CI. Pastikan job build hanya punya secret yang benar-benar perlu.
Penutup
Security yang bagus sering bukan soal tool paling mahal. Kadang cuma soal nggak percaya buta pada output build sendiri.
Kalau lu sedang bangun app, website, atau device workflow, simpan satu prinsip ini: yang user terima adalah artifact final, bukan niat baik developer di source code. Jadi artifact final juga harus diaudit.
Follow rafli.dev kalau lu suka insight tech yang praktis, jujur, dan bisa langsung dipakai buat kerja builder sehari-hari.