3 Jam Pertama Ponimu Rilis: Berburu Bug


Hari itu Selasa, 31 Juli 2018. Saya baru banget bangun karena kecapean di hari sebelumnya, inget kalo Ponimu rilis beberapa jam lalu. Sebetulnya lagi ada tasklist yang harus di kerjain, cuma karena web kaya Ponimu ini baru banget di Indo, kelihatannya kita bakal coba lihat-lihat webnya.

Setelah berhasil mendaftar dan login, saya langsung lihat semua halamannya, perhatiin beberapa benda, dan memutuskan untuk coba lihat bagian belakangnya.

Bagian belakang (API)nya cukup mantep. Mereka pake JWT untuk otorisasi. Algoritma signaturenya juga kuat. Cuma emang ada beberapa yang agak ngeganjel sih, kaya kenapa request OPTION dilakukan beberapa kali? Mungkin karena store vue mereka kepisah kali ya? Entah sih ini bukan masalah besar.

JWT.IO debugging tools, https://jwt.io/#debugger-io

Dari sini saya mulai melihat beberapa masalah yang bisa timbul, masalah tersebut akan saya bahas secara terurut berdasarkan waktu pelaporan.

⚠ Disclaimer ⚠

Saat ini bug yang dilaporkan pada post ini sudah diatasi pada minggu pertama soft launching. Tim dari Ponimu langsung merespon cepat laporan bug yang saya kirim waktu itu, jadi post ini sifatnya hanya untuk dokumentasi bug yang saya temukan.

Data Sensitif

Kali ini webnya ngasih endpoint untuk profil, kalo kita lihat isi dalamnya, semuanya disajikan lengkap. Ada nama, email, nickname, birthdateemailtelephone number, subscribed total, dan beragam data lainnya. Kalo dilihat, sebetulnya data yang saya bold ini akan normal ada karena saya yang login. Nah, kalo ternyata ini juga berlaku untuk profil orang lain, bagaimana?

curl 'https://api.ponimu.com/api/user-infos-ext/(idusernya)'
    -H 'Content-Type: application/json;charset=UTF-8' 
    -H 'Accept: application/json, text/plain, */*'
    -H 'Authorization: Bearer (tokenmu disini)'

Seperti yang kita lihat, hasil dari endpoint tersebut bener-bener ngasih (hampir) semua data akun kita, dan ini juga berlaku untuk akun orang lain. Jadi kalo saya ingin tahu si Z itu teleponya apa, sama emailnya apa, kita bisa kok cari langsung, di bruteforce dari 1-sekian.

Dan menurut saya ini potensi masalah privasi sih. Soalnya kita tau kalo orang lain bisa farming email, kita bisa kirim spam nggak jelas ke alamat yang dimention.

Otentikasi

Otentikasi (Authentication) itu penting banget, dan masalah yang saya temukan di Ponimu adalah… login sama sekali tidak dilindungi. Dalam artian, karena otentikasi itu menghasilkan token/hak akses yang dipake di mana-mana, maka idealnya fitur tersebut sebaiknya tidak menghasilkan token tanpa membuktikan jika pengguna itu sebetulnya pengguna asli atau bot.

curl 'https://api.ponimu.com/api/authenticate' 
    -H 'Content-Type: application/json;charset=UTF-8' 
    -H 'Accept: application/json, text/plain, */*'
    --data-binary '{"username":"(username-kalian)","password":"(password-kalian)"}' 

Kalau kita perhatikan dari requestnya, endpoint login ini benar-benar apa adanya banget. Ini masalah juga. Saya bisa melakukan bruteforce untuk mencari password atau mungkin karna bosan, mau ngebajak anime yang disimpan

Admin Panel

Karena masih penasaran dengan bug lain, hari itu saya coba cek home page APInya. Karena saya tau mereka menggunakan JHipster, dan saya lihat banyak plugin untuk front-end, jadi mungkin ada clue untuk kita main ke url tersebut?

*masukkan urlnya*

*enter*

Halaman muka admin panel Ponimu

well, halo Mumu.

Saya coba masukan kredensial akun saya dan saya dapat akses ke admin panelnya.

Halaman dasbor admin panel Ponimu

Ehm… yup, saya tau mungkin saya tidak sepenuhnya dapat akses ke admin panelnya, tapi saya bisa dong set status seluruh infrastrukturnya jadi mode maintenance? (Spoiler: saya batal explore, soalnya takut dianggap beneran merusak fasilitas)

But wait, there’s more.

Setelah saya report beberapa bug, saya baru mulai eksplorasi lagi beberapa hari kemudian. Bug-bug kali ini lebih mengarah ke sistem API mereka. Kebanyakan bugnya adalah kita dapat mengganti hal yang harusnya nggak bisa kita ganti. Pembahasan lebih detil dilakukan dibawah dan yes, yang ini juga sudah diperbaiki.

Ganti Badge dan Pake Gambar dari Gravatar

Bahasa di mereka Badge itu Legend (User Reputation), jadi kita bakal pake istilah Legend buat itu ya.

Legend yang harusnya cuma bisa milih dari apa yang kita punya, bisa saya timpa dengan apa yang saya nggak punya badgenya. Contohnya, saya bisa ganti badge saya jadi Ponimu Legend (menarik, soalnya warnanya emas sih), padahal Ponimu baru rilis beberapa hari lalu.

Illustrasi (gambar asli hilang karna hard disk saya rusak senin lalu.)
curl -X PUT \
  https://api.ponimu.com/api/user-infos-ext/92 \
  -H 'Authorization: Bearer (token)' \
  -H 'Content-Type: application/json' \
  -d '{"imgUrl":"https://www.gravatar.com/avatar/a8894cf0b08080e1475efee4c2046d7e?s=300","birthdate":"1997-04-14T00:00:00Z", "legendValue":"ponimu-legend"}'

Ganti Profil Orang Lain

Kali ini kita coba ganti profil orang lain, dengan endpoint yang sama, tapi ganti referensi IDnya.

curl -X PUT \
  https://api.ponimu.com/api/user-infos-ext/824 \
  -H 'Authorization: Bearer (token)' \
  -H 'Content-Type: application/json' \
  -d '{"imgUrl":"https://www.gravatar.com/avatar/a8894cf0b08080e1475efee4c2046d7e?s=300","birthdate":"1997-04-14T00:00:00Z", "legendValue":"ponimu-starter"}'

Notice si 92 pada endpoint sebelumnya saya ganti jadi 824. Hal ini berhasil dilakukan dengan token authorization saya(92), bukan yang punya akun (824) tersebut.

Ilustrasi akun target setelah perubahan (notice bagian badge, tanggal lahir dan gambarnya)

More eager, more access, RESET ALL PASSWORD!

Dari url post tersebut, saya mulai curiga dengan endpoint yang “lain”. Kita bisa hapus -ext pada fragment endpoint sebelumnya, dan kita bisa lihat ada apa saja di sana:

curl -X GET \
  https://api.ponimu.com/api/user-infos/824 \
  -H 'Authorization: Bearer (token)'

Yay, kita nemu activeToken. Yay, tinggal ganti passwordnya deh.

curl 'https://api.ponimu.com//api/account/change-password' 
-H 'Authorization: Bearer (token korban)'
-H 'Content-Type: text/plain'
--data-binary '(password baru)'

Bulan Lahirku Kok Bulan Lalu ya?

Bug yang satu ini ada di halaman profil. Bulan lahir yang kita tulis di halaman preferensi profil, ditampilkan dengan salah di halaman profil kita. Iya, itu doang bugnya buat yang ini.

Kesimpulan

Karena bug sifatnya insidentil dan tidak menententu, serta kadang menjengkelkan (buat developernya, karena memang kadang susah dideteksi), ada baiknya kita terlibat aktif untuk melaporkan bug tersebut pada pemiliknya, bukan ke publik langsung.

Anyway, karena laporan bug-bug ini, Tim Ponimu memutuskan untuk menganugrahkan saya reputasi khusus (link profil).

Bug Hunter Badge

Peralatan yang digunakan

  • Chrome DevTools
  • Postman
  • cUrl
  • JWT.IO Debug Tools
  • Gimp (buat hide data sensitif)
Repurika: Mata ne! (See you)
Replica’s Ending Screen of World Trigger, Copyright TOEI Animations