OPSEC untuk developer: jejak digital yang tanpa sadar ikut terbit
Email dan zona waktu di commit Git, rahasia yang tertinggal di riwayat repo, koordinat GPS di foto, subdomain di log Certificate Transparency, dan folder .git yang ikut ter-deploy: cara mengecek dan menutup kebocoran informasi yang paling sering dibuat developer.
- opsec
- privasi
- osint
OPSEC (operations security) lahir dari Perang Vietnam. Pada 1966 militer Amerika Serikat membentuk tim bersandi Purple Dragon untuk menyelidiki mengapa lawan seolah sudah tahu sebelum operasi dimulai. Kesimpulannya mengejutkan: kebocoran terbesar bukan dokumen rahasia, melainkan potongan informasi biasa yang bisa diamati siapa saja, seperti jadwal, rutinitas, dan pola komunikasi. Satu per satu potongan itu tidak berbahaya. Dirangkai, potongan itu membuka rencana operasi.
Developer menghasilkan potongan seperti itu setiap hari. Commit, foto, sertifikat TLS, dan header HTTP tidak ada yang rahasia, tetapi bersama-sama bisa mengungkap identitas, lokasi, dan infrastruktur. Tulisan ini membahas kebocoran yang paling sering terjadi, cara mengeceknya sendiri, dan cara menutupnya.
Mulai dari model ancaman
OPSEC bukan daftar alat, melainkan proses lima langkah yang dirumuskan dari pengalaman Purple Dragon dan kemudian dibakukan dalam program OPSEC nasional Amerika Serikat (NSDD 298, 1988):
| Langkah | Pertanyaan | Contoh bagi developer |
|---|---|---|
| Identifikasi informasi kritis | Apa yang harus dilindungi? | identitas di balik username, alamat rumah, kunci API, infrastruktur internal |
| Analisis ancaman | Siapa yang mungkin mencarinya? | bot pemindai kunci, pelaku doxing, penyerang yang mengincar klien |
| Analisis kerentanan | Lewat mana informasi itu terlihat? | metadata commit, EXIF foto, log CT, file yang ikut ter-deploy |
| Penilaian risiko | Seberapa besar peluang dan dampaknya? | kunci cloud yang bocor jauh lebih mendesak daripada zona waktu commit |
| Penerapan tindakan | Tindakan apa yang sepadan? | email noreply, rotasi kunci, hapus metadata, autentikasi di staging |
Langkah kedua menentukan segalanya. Developer yang ingin tetap anonim di balik username butuh tindakan yang jauh lebih ketat daripada developer yang hanya ingin kunci API-nya aman, jadi pilih bagian di bawah yang sesuai dengan model ancaman Anda.
Commit Git: nama, email, dan jam kerja
Setiap commit menyimpan nama dan email author serta committer, lengkap dengan waktu dan zona waktunya. Semuanya ikut terbit saat repo di-push ke tempat publik. Cek apa yang selama ini tercatat:
git log --format='%an <%ae>' | sort | uniq -c | sort -rngit log --format='%ad' --date=format:'%H:00 %z' | sort | uniq -c | sort -rnHasil pertama sering memunculkan email kantor atau email lama yang terlupa. Hasil kedua memperlihatkan zona waktu (+0700 berarti WIB) dan jam-jam aktif, cukup untuk menebak lokasi dan rutinitas seseorang. Orang lain bahkan tidak perlu meng-clone repo: menambahkan .patch di akhir URL commit GitHub menampilkan baris From: berisi nama dan email author.
https://github.com/<user>/<repo>/commit/<sha>.patchCara menutupnya:
- Di GitHub, buka Settings → Emails, lalu aktifkan Keep my email addresses private dan Block command line pushes that expose my email. GitHub kemudian menyediakan alamat berbentuk
ID+username@users.noreply.github.com. - Pakai alamat itu sebagai email Git. Untuk memisahkan identitas kerja dan pribadi,
includeIfmembuat repo di folder tertentu otomatis memakai email lain. - Zona waktu diambil dari pengaturan sistem. Bila itu termasuk informasi kritis, commit bisa dibuat dalam UTC dengan
TZ=UTC git commit. Pola jam aktif tetap terlihat dari waktu push dan aktivitas lain.
[user]
name = nama-publik
email = 12345+username@users.noreply.github.com
# Repo di dalam ~/kerja/ memakai email kantor dari file terpisah
[includeIf "gitdir:~/kerja/"]
path = ~/.gitconfig-kerjaRahasia yang tertinggal di riwayat
Menghapus file .env lewat commit baru tidak menghapusnya dari riwayat; isinya masih bisa diambil dari commit sebelumnya. Bot terus memindai repo publik untuk mencari kunci, dan berbagai eksperimen menunjukkan kunci yang bocor bisa dicoba orang lain dalam hitungan menit. Urutan penanganannya:
- Rotasi dulu. Cabut kunci di penyedianya dan buat yang baru. Kunci yang pernah terbit harus dianggap sudah diketahui orang, apa pun yang terjadi pada riwayat repo.
- Cari kebocoran lain di seluruh riwayat, misalnya dengan gitleaks:
gitleaks git -v. - Bersihkan riwayat dengan git filter-repo di clone baru, lalu push ulang dengan
--force(contoh di bawah). - Cegah terulang. Masukkan
.env*ke.gitignore(kecuali contoh seperti.env.example) dan aktifkan secret scanning serta push protection di pengaturan keamanan repo.
# hapus file dari seluruh riwayat
git filter-repo --invert-paths --path .env
# atau ganti string rahasia (satu per baris di rahasia.txt)
git filter-repo --replace-text rahasia.txtFork, clone milik orang lain, dan cache (termasuk referensi pull request di GitHub) tidak ikut bersih. Itu sebabnya rotasi selalu menjadi langkah pertama.
Khusus Next.js, variabel lingkungan berawalan NEXT_PUBLIC_ disisipkan ke JavaScript yang dikirim ke browser saat build. Jangan pernah menaruh kunci rahasia di sana. Situs ini, misalnya, hanya membaca kredensial SMTP di server lewat Server Action, dan nilainya diatur di panel hosting, bukan di repo.
Metadata di foto dan dokumen
Foto dari ponsel umumnya membawa EXIF: model perangkat, waktu pengambilan, dan sering kali koordinat GPS. Pada Desember 2012, foto John McAfee yang diterbitkan majalah Vice masih menyimpan koordinat GPS, sehingga lokasinya di Guatemala langsung diketahui publik. Periksa dan bersihkan dengan ExifTool:
exiftool -gps:all -datetimeoriginal foto.jpg # lihat lokasi dan waktu
exiftool -all= -overwrite_original foto.jpg # hapus semua metadataBanyak media sosial menghapus EXIF saat foto diunggah, tetapi file yang dikirim sebagai dokumen, seperti lampiran email atau fitur "kirim sebagai file" di aplikasi chat, biasanya sampai utuh beserta metadatanya.
Dokumen PDF dan Office menyimpan nama author, organisasi, versi perangkat lunak, dan waktu pembuatan. exiftool laporan.pdf memperlihatkannya, dan mat2 membuat salinan bersih: mat2 laporan.pdf menghasilkan laporan.cleaned.pdf.
Tangkapan layar juga perlu diperiksa. Screenshot terminal sering memperlihatkan user@hostname di prompt, path seperti /home/nama-asli/, alamat IP internal, atau nama klien di tab yang terbuka. Gambar bahkan bisa menyimpan lebih dari metadata: data juga bisa disembunyikan di piksel itu sendiri, seperti dibahas di tulisan tentang Chi-Square Attack dan RS Analysis.
Yang ikut ter-deploy
Server produksi adalah tempat yang paling mudah diperiksa orang lain, dan juga paling mudah diperiksa sendiri:
curl -sI https://domain-anda.com | grep -iE '^(server|x-powered-by):'
curl -s https://domain-anda.com/.git/HEAD
curl -s -o /dev/null -w '%{http_code}\n' https://domain-anda.com/.env- Folder
.git/yang bisa diakses memungkinkan seluruh kode sumber beserta riwayatnya diunduh ulang dengan alat seperti git-dumper. Bila perintah kedua menampilkan teks sepertiref: refs/heads/main, itu masalah serius. - Header versi seperti
ServerdanX-Powered-Bymemberi tahu penyerang perangkat lunak apa yang perlu dicari celahnya. Next.js mengirimX-Powered-By: Next.jssecara bawaan; situs ini mematikannya denganpoweredByHeader: false. - Source map (
*.js.map) di produksi mengembalikan kode sumber asli lengkap dengan komentarnya. Next.js tidak membuatnya untuk browser saat build produksi kecualiproductionBrowserSourceMapsdiaktifkan. - Pesan error yang terlalu rinci, seperti stack trace, path server, atau query SQL, cukup masuk log, tidak perlu tampil di halaman.
Ada juga kebocoran yang tidak bisa dimatikan. Setiap sertifikat TLS dari CA publik dicatat di log Certificate Transparency yang bisa dibaca siapa saja, jadi nama subdomain seperti staging. atau admin-lama. sudah publik sejak sertifikatnya terbit:
https://crt.sh/?q=%25.domain-anda.comJangan mengandalkan nama subdomain yang sulit ditebak sebagai pengaman. Lindungi lingkungan staging dengan autentikasi, atau pakai sertifikat wildcard bila nama subdomain itu sendiri sensitif.
Satu identitas, satu kompartemen
Username yang sama di banyak platform memudahkan orang merangkai akun-akun Anda; alat OSINT seperti Sherlock memeriksa satu username di ratusan situs sekaligus. Kasus klasiknya Ross Ulbricht, pendiri Silk Road. Penyidik menemukan unggahan lama berusername "altoid" yang mempromosikan Silk Road, lalu unggahan lain dari "altoid" di forum Bitcoin yang mencantumkan alamat Gmail atas nama aslinya.
Kompartemen yang rapi berarti:
- email terpisah untuk keperluan berbeda, atau alias (misalnya dari Proton Pass, SimpleLogin, atau Firefox Relay) agar alamat utama tidak tersebar;
- profil browser atau container terpisah, agar cookie dan sesi akun kerja, pribadi, dan riset tidak bercampur;
- username dan foto profil berbeda untuk identitas yang memang ingin dipisahkan, karena foto juga bisa dicocokkan lewat pencarian gambar.
Kompartemen hanya sekuat momen terlemahnya. Hector Monsegur ("Sabu") dari LulzSec dilaporkan teridentifikasi setelah sekali saja masuk ke server IRC tanpa Tor, sehingga alamat IP aslinya tercatat.
Kebocoran lewat kebiasaan
Tidak semua kebocoran datang dari kode:
- Pada Januari 2018, peta panas global Strava memperlihatkan rute lari personel militer di sekitar pangkalan di daerah konflik, karena data GPS dari jam pintar mereka diunggah otomatis.
- Pada 2020, mantan Perdana Menteri Australia Tony Abbott mengunggah foto boarding pass ke Instagram. Kode booking di dalamnya cukup bagi seorang peneliti keamanan untuk masuk ke halaman pemesanan maskapai dan menemukan nomor paspornya.
- Foto meja kerja sering ikut memperlihatkan sticky note berisi password, dashboard internal di layar, atau kartu identitas kantor.
Pelajarannya sama: informasi yang terasa remeh bagi kita, seperti rute lari atau tiket pesawat, adalah potongan berharga bagi orang yang sedang menyusun profil.
Daftar periksa
- Model ancaman jelas: apa yang dilindungi, dan dari siapa.
- Email commit memakai alamat noreply, dan push yang membocorkan email diblokir.
- Riwayat repo sudah dipindai, dan kunci yang pernah bocor sudah dirotasi.
- Tidak ada rahasia di variabel
NEXT_PUBLIC_*atau di bundle JavaScript. - Foto dan dokumen dibersihkan metadatanya sebelum dibagikan.
/.git/,.env, dan source map tidak bisa diakses dari luar, dan header versi dimatikan.- Subdomain di crt.sh sudah dicek, dan staging dilindungi autentikasi.
- Identitas yang ingin dipisahkan memakai email, username, dan profil browser yang berbeda.
OPSEC bukan pekerjaan sekali jalan. Ulangi lima langkah tadi setiap kali ada yang berubah: pekerjaan baru, repo publik baru, atau kebiasaan baru. Kalau Anda menemukan kebocoran di situs ini, laporkan lewat security.txt.