Situs HaveIBeenPwned.com (dibaca “have I been owned”, artinya “apakah (akun) saya dipakai orang lain?”) ini sering dipakai untuk mencari informasi apakah alamat surel (email) dan kata sandi (password) Anda pernah bocor dari situs, aplikasi, atau sistem tertentu.
Saya masih ingat dengan kasus bocornya data pengguna Bukalapak dan Tokopedia beberapa tahun lalu yang sempat buat masyarakat panik, dan untungnya tim pengembang di balik situs ini berhasil mengekstrak data pengguna (alamat surel/email, nomor telepon) yang bocor ke dalam situs tersebut, sehingga para korban dapat mengecek apakah akun mereka juga telah dibocorkan.
Nah, kalau bahas soal NIK (Nomor Induk Kependudukan), sebenernya sering bocor juga sih. Mulai dari laman pencarian Daftar Pemilih Tetap (DPT) Pemilihan Umum yang kerap telanjur dimasukkan ke dalam Google Search dan mesin pencari lainnya, bahkan adanya grup-grup investasi palsu di Telegram yang buka-bukaan data NIK dan nomor rekening masyarakat.
Lanjutan kasus grup HQSahamIDX palsu
Nah, kemarin temen gw pr0xy sempat kasih tahu soal grup HQSahamIDX palsu yang terciduk itu. Dan jujur aja gw prihatin sama admin grup palsu tersebut yang membagi-bagikan Nomor Induk Kependudukan secara gratis, tis, tis!!! Eh beneran lho! NIK mereka asli dan bahkan bisa diverifikasi di dalam aplikasi PeduliLindungi. Kalau seandainya nomor teleponnya juga ga disensor sama adminnya, siapa tahu saya juga bisa download sertifikat vaksinnya secara sekaligus!
Oke, di bagian kiri gambar tersebut adalah screenshot dari aplikasi Telegram. Karena grup ini adalah grup publik, saya juga bisa mengakses postingan yang sama di luar aplikasi Telegram dengan menyalin tautan pesan publik (“Copy Message Link”) dan mengaksesnya di peramban (web browser) dengan mudah. Saya tidak tau kenapa preview dari chat tersebut tidak bisa dimasukkan ke dalam Internet Archive Wayback Machine, tapi intinya kita masih bisa ekstrak isi pesannya.
Oh iya, karena grup ini publik dan malah meng-encourage (menyemangati) untuk masukkin member sebanyak-banyaknya, seseorang bisa saja membuat sebuah aplikasi client Telegram baru yang menyusup ke dalam grup itu dan mengekstrak semua data pribadi yang dibagikan di dalam chat tersebut. Oh iya, data pribadi yang dimasukkin itu juga bisa berasal dari korban penipuan, lho!
Karena itu jujur aja saya mau nanya nih, menurut kalian perlu tidak untuk buat semacam situs HaveIBeenPwned, tapi lebih ke arah kebocoran Nomor Induk Kependudukan alias nomor KTP? Kalau kalian mau jawab sekarang ini formnya ya.
Emang NIKnya aman dimasukkin di situ? Apa nanti ga diciduk pemerintah karena nyimpan segitu banyak NIK yang bocor?
Nah, itu dia masalahnya. Kita harus ngebuktiin bahwa:
- NIK yang masuk di websitenya aman, dan
- Kita bisa ngebuktiin bahwa NIK yang masuk aman, dan
- Semua ini bisa dibuktikan tanpa campur tangan pemerintah/kementerian/dinas terkait (independen), termasuk kepolisian dan lembaga-lembaga terkait (BIN, BSSN, dan sebagainya)
Website HaveIBeenPwned.com ini bersifat closed-source, artinya tidak semua data di dalam situsnya itu dapat diakses dan diunduh oleh publik meskipun dengan alasan yang baik. Jika kita melakukan hal yang sama terhadap NIK, kita mungkin bisa tepar ngurusin masalah perizinan pemerintah dan kepatuhan terhadap rancangan UU PDP nanti. Saat ini peraturan pemerintah tentang perlindungan data pribadi ini hanya baru di level peraturan menteri (Kominfo), sedangkan UU yang sesungguhnya masih “digoreng” di Senayan.
Nah karena itu, saya sendiri merekomendasikan beberapa hal berikut ini:
- Kita langsung open source dan open data, jadi siapapun (pemerintah, masyarakat) bisa mengunduh database kebocoran NIKnya secara mudah
- Setiap pengguna harus dapat mengaksesnya (melakukan pencarian NIK bocor setelah datanya diunduh) secara luring (offline), sehingga NIK yang dicari sulit diambil melalui lalu lintas jaringan komputer (misal: dibandingkan dengan mengetik NIK mereka di dalam sebuah website)
- TIDAK ADA NIK DI DATA-NYA! Oke, mungkin ini bersifat aneh, tetapi data yang kita simpan ini hanya terbatas terhadap:
- Digit ketiga dan keempat dalam NIK, yang menandakan kode kota menurut data dari Kemendagri dan Badan Pusat Statistik (BPS) di mana NIK tersebut pertama kali didaftarkan,
- Tanggal lahir korban, yang sangat mudah diekstrak dari NIK,
- Jenis kelamin korban sesuai KTP, karena memengaruhi format penulisan NIK tersebut dan untuk meningkatkan tingkat entropy terhadap proses pencarian identitas korban yang terenkripsi, serta
- Nama korban dalam format Nama Depan + Inisial, misalnya Julia ADS. Kecuali dengan nama sebutan tertentu seperti Muhammad Ramadhan JH dan Ni Putu Dela BRF.
- Nilai tingkat entropy dari poin 1-3 di atas adalah 30 (jumlah kota dan kabupaten dalam sebuah provinsi, estimasi diambil dari Jawa Barat) * 366 (hari dalam setahun, termasuk kabisat) * 100 (kombinasi akhiran tahun ’00 hingga ’99) * 2 (jenis kelamin). Artinya, seorang peretas data membutuhkan lebih dari 2 juta kali pencarian untuk dapat melakukan brute-force untuk melihat semua daftar identitas yang bocor.
- Dan seandainya jika semua data yang terenkripsi di sini berhasil diretas, sang peretas masih belum dapat mengetahui lokasi korban tanpa kode provinsi (2 digit awal pada NIK). Berarti jika mereka menemukan seseorang bernama Muhammad Ramadhan JH dengan tanggal lahir 23 Januari 1999 dan kode kab/kota 73, dia bisa saja berdomisili di kota Jakarta Pusat (dengan NIK 3173xx230199xxxx), Pematang Siantar (1273xx230199xxxx), Pagar Alam (1673xx230199xxxx), Salatiga (3373xx230199xxxx), dan sebagainya.
Kita juga butuh dua tim lagi: GRC dan legal, dan targetnya sih agar sistem yang kita buat ini lulus audit independen dan juga memiliki website resmi yang terdaftar sebagai penyelenggara sistem elektronik (PSE) resmi, meskipun bersifat open-source dan datanya juga dapat diakses secara luring/offline. Jadi, ujung-ujungnya, proyek ini bisa dapat kepercayaan baik dari para pakar keamanan hingga pemerintah itu sendiri.
Nah jadi balik lagi nih, menurut kalian apakah kita perlu buat situs semacam ini?
Update 9 September 2021
Ada yang tanya ke kita apakah ada kasus di mana sebuah kode kota/kabupaten hanya dimiliki oleh 1 provinsi saja, sehingga seseorang dapat langsung menebak provinsi dan kab/kota korban berasal. Untuk membuktikannya, saya membuat program Python3 sebagai berikut:
#!/usr/bin/python3
import requests
import json
stat = {}
i = 1
while i < 10:
j = 1
while j < 10:
r = requests.get("https://sig-dev.bps.go.id/restDropDown/getwilayah/level/kabupaten/parent/" + str(i) + str(j))
js = r.json()
if len(js) == 0:
break
for e in js:
kode = int(e["kode"]) % 100
if kode not in stat:
stat[kode] = {
"total": 0,
"prov": []
}
stat[kode]["total"] += 1
stat[kode]["prov"].append((int(e["kode"]) - kode) / 100)
j += 1
i += 1
print(json.dumps(stat))
{"1": {"total": 33, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 64.0, 65.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 81.0, 82.0, 91.0]}, "2": {"total": 32, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 32.0, 33.0, 34.0, 35.0, 36.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 64.0, 65.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 81.0, 82.0, 91.0]}, "3": {"total": 32, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 32.0, 33.0, 34.0, 35.0, 36.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 64.0, 65.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 81.0, 82.0, 91.0]}, "4": {"total": 32, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 32.0, 33.0, 34.0, 35.0, 36.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 64.0, 65.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 81.0, 82.0, 91.0]}, "5": {"total": 29, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 32.0, 33.0, 35.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 64.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 81.0, 82.0, 91.0]}, "6": {"total": 26, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 32.0, 33.0, 35.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 71.0, 72.0, 73.0, 74.0, 76.0, 81.0, 82.0, 91.0]}, "7": {"total": 24, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 32.0, 33.0, 35.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 71.0, 72.0, 73.0, 74.0, 81.0, 82.0, 91.0]}, "8": {"total": 24, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 32.0, 33.0, 35.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 71.0, 72.0, 73.0, 74.0, 81.0, 82.0, 91.0]}, "9": {"total": 22, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 32.0, 33.0, 35.0, 53.0, 61.0, 62.0, 63.0, 64.0, 71.0, 72.0, 73.0, 74.0, 81.0, 91.0]}, "10": {"total": 18, "prov": [11.0, 12.0, 13.0, 14.0, 16.0, 18.0, 32.0, 33.0, 35.0, 53.0, 61.0, 62.0, 63.0, 71.0, 72.0, 73.0, 74.0, 91.0]}, "11": {"total": 18, "prov": [11.0, 12.0, 13.0, 16.0, 18.0, 32.0, 33.0, 35.0, 53.0, 61.0, 62.0, 63.0, 64.0, 71.0, 72.0, 73.0, 74.0, 91.0]}, "12": {"total": 15, "prov": [11.0, 12.0, 13.0, 16.0, 18.0, 32.0, 33.0, 35.0, 53.0, 61.0, 62.0, 72.0, 73.0, 74.0, 91.0]}, "13": {"total": 11, "prov": [11.0, 12.0, 16.0, 18.0, 32.0, 33.0, 35.0, 53.0, 62.0, 73.0, 74.0]}, "14": {"total": 8, "prov": [11.0, 12.0, 32.0, 33.0, 35.0, 53.0, 73.0, 74.0]}, "15": {"total": 8, "prov": [11.0, 12.0, 32.0, 33.0, 35.0, 53.0, 73.0, 74.0]}, "16": {"total": 7, "prov": [11.0, 12.0, 32.0, 33.0, 35.0, 53.0, 73.0]}, "17": {"total": 7, "prov": [11.0, 12.0, 32.0, 33.0, 35.0, 53.0, 73.0]}, "18": {"total": 7, "prov": [11.0, 12.0, 32.0, 33.0, 35.0, 53.0, 73.0]}, "71": {"total": 32, "prov": [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 51.0, 52.0, 53.0, 61.0, 62.0, 63.0, 64.0, 65.0, 71.0, 72.0, 73.0, 74.0, 75.0, 81.0, 82.0, 91.0]}, "72": {"total": 21, "prov": [11.0, 12.0, 13.0, 15.0, 16.0, 18.0, 21.0, 31.0, 32.0, 33.0, 35.0, 36.0, 52.0, 61.0, 63.0, 64.0, 71.0, 73.0, 74.0, 81.0, 82.0]}, "73": {"total": 12, "prov": [11.0, 12.0, 13.0, 14.0, 16.0, 31.0, 32.0, 33.0, 35.0, 36.0, 71.0, 73.0]}, "74": {"total": 11, "prov": [11.0, 12.0, 13.0, 16.0, 31.0, 32.0, 33.0, 35.0, 36.0, 64.0, 71.0]}, "75": {"total": 7, "prov": [11.0, 12.0, 13.0, 31.0, 32.0, 33.0, 35.0]}, "19": {"total": 4, "prov": [12.0, 33.0, 35.0, 53.0]}, "20": {"total": 4, "prov": [12.0, 33.0, 35.0, 53.0]}, "21": {"total": 4, "prov": [12.0, 33.0, 35.0, 53.0]}, "22": {"total": 4, "prov": [12.0, 33.0, 35.0, 73.0]}, "23": {"total": 3, "prov": [12.0, 33.0, 35.0]}, "24": {"total": 3, "prov": [12.0, 33.0, 35.0]}, "25": {"total": 4, "prov": [12.0, 33.0, 35.0, 73.0]}, "76": {"total": 5, "prov": [12.0, 13.0, 32.0, 33.0, 35.0]}, "77": {"total": 4, "prov": [12.0, 13.0, 32.0, 35.0]}, "78": {"total": 3, "prov": [12.0, 32.0, 35.0]}, "79": {"total": 2, "prov": [32.0, 35.0]}, "26": {"total": 3, "prov": [33.0, 35.0, 73.0]}, "27": {"total": 2, "prov": [33.0, 35.0]}, "28": {"total": 2, "prov": [33.0, 35.0]}, "29": {"total": 2, "prov": [33.0, 35.0]}}
Kalau kita mapping distribusi datanya,
- poros x bawah: kode kab (01 – 69)
- poros x atas: kode kota (71 – 99)
- poros y: jumlah provinsi yang memiliki kode tersebut (1 – 34)
Berdasarkan data di atas, kita menemukan bahwa kasus terburuk (worst case) dari kasus yang disampaikan bahwa kode kab/kota orang tersebut hanya tersedia di 2 provinsi, dan berdasarkan analisis tersebut kedua provinsi ini adalah provinsi Jawa Barat dan Jawa Timur. Kedua provinsi ini sangat luas dan berjauhan (disekat oleh provinsi Jawa Tengah dan Daerah Istimewa Yogyakarta), sehingga kota/kabupaten korban masih sulit dilacak secara fisik, meskipun secara data kab/kota misterius tersebut dapat berada entah di Jawa Barat atau Jawa Timur.
Leave a Reply