Tuesday, May 16, 2017

Bug Go-Jek

Bug Gojek (Agustus 2015)

Tulisan berikut ini ditulis akhir bulan Desember 2015. Saya sudah mengirimkan ini ke pihak Gojek dan mereka minta waktu untuk perbaikan. Mereka meminta saya menunda sampai tanggal 10 Januari 2016 untuk menerbitkan ini.
Karena saya sudah mengecek bug gojek dua kali (Agustus dan Desember 2015), saya tidak mengecek lagi apakah bug-bug ini saat ini masih ada atau tidak (capek lah ngecek terus, ini kan kerjaan iseng gak dibayar). Tulisan ini tidak diedit lagi (jadi jika Anda membaca “saat ini bug masih ada” artinya itu masih ada ketika tulisan ini dibuat, yaitu akhir Desember 2015).
Yang perlu saya tambahkan: bug yang ada kemungkinan bukan hanya yang saya tulis di bawah ini, masih ada banyak lagi (ada puluhan endpoint API gojek, banyak yang berpotensi punya bug). Karena saya berlokasi di Thailand, saya hanya bisa melakukan testing terbatas (bahkan saya belum pernah mencoba memakai Gojek secara langsung). Silakan coba-coba untuk memeriksa bagi yang iseng mencoba (saya sudah membuat tulisan bagaimana melakukan Reverse Engineering APK Android sebagai panduan bagi pemula).
—————-
Jika Anda belum membaca, sebaiknya baca dulu pengantar seri ini: Mencari dan melaporkan bug security. Perlu dicatat: bug ini sudah dilaporkan (akhir sejak Agustus 2015). Sebagian sudah diperbaiki, tapi banyak lagi belum. Bug ini juga sudah ditemukan banyak orang lain (saya sempat melempar pertanyaan ini di facebook wall saya, dan hasilnya saya dijapri beberapa orang).
Gojek
Bug ini saya temukan sekitar Agustus 2015. Pihak Gojek cukup responsif dalam menanggapi laporan saya, walaupun ternyata banyak yang tidak diperbaiki hampir 5 bulan kemudian. Saya juga diberi kredit 1 juta rupiah, yang saya berikan ke adik saya, tapi beberapa bulan kemudian sistem gojek error, dan saldonya jadi nol.
Saya hanya mempelajari aplikasi gojek versi Android, tapi karena backend-nya sama, maka bug-bug ini berlaku untuk iOS juga. Bug utama gojek adalah: API request tidak menggunakan session, dan berikutnya adalah: tidak ada batasan siapa yang bisa mengupdate data.

Data yang bocor

Summarynya kira-kira seperti ini:
  • Siapapun bisa mencari customer ID berdasarkan telepon atau nama atau email
  • Siapapun bisa mengubah pulsa driver gojek manapun
  • Siapapun bisa melihat data pribadi driver gojek, termasuk foto, alamat, dan bahkan nama ibu kandung
  • Siapapun bisa mendapatkan nama user, email, no HP user lain
  • Siapapun bisa mengganti no HP dan nama user lain, tanpa perlu tahu passwordnya
  • Siapapun bisa melihat order history orang lain
Order history gojek cukup komprehensif: dari mana, ke mana lewat route mana, driver mana yang mengambil penumpang, dsb. Jika pesanannya adalah makanan, maka makanan yang dipesan dan harganya juga bisa dilihat.
Ini adalah contoh dimana saya melihat aplikasi ini dari sisi iseng: pengen tau seberapa banyak hal yang dilakukan oleh app mobile, dan seberapa banyak yang ditangani server. Ketika mulai melihat bahwa aplikasi ini tidak menggunakan session management untuk menandai bahwa yang melakukan request adalah user yang sudah login, maka saya mulai curiga bahwa data akan bocor.
Dan ternyata memang benar: data pribadi seseorang yang bocor banyak sekali. Ternyata salah seorang rekan saya sudah pernah menemukan ini tapi belum ditindaklanjuti karena pihak gojek masih membuat sistem mereka lebih stabil, dan ternyata bug ini sudah ada cukup lama.
Di sini saya sebenarnya agak merasa bimbang: apakah sebaiknya cepat-cepat diberitahu ke publik, bahwa mungkin ada orang yang mencuri data diri Anda (terutama puluhan ribu driver gojek yang data lengkapnya gampang diakses). Atau tunggu dulu, kasihan ini startup baru. Kalau buru-buru diumumkan, tapi belum diperbaiki, siapapun bisa membuat skrip untuk memporak-porandakan seluruh data-data user dan driver. Bayangkan jika ada leak seperti Ashley-Madison.
Saya sendiri sebenarnya akan merasa risih Andaikan nama, nomor telepon, alamat rumah saya, alamat tujuan saya naik gojek bisa diakses siapa saja di Internet. Tapi karena saya nggak tinggal di Indonesia, jadi saya tidak benar-benar merasakan itu.
Akhirnya saya memutuskan untuk menunggu saja. Salah satu alasan saya adalah: waktu itu banyak orang merasa positif dengan keberadaan Gojek, dan driver maupun penumpang sangat diuntungkan (karena adanya sistem referral), tidak seperti beberapa bulan terakhir di mana ada banyak drama.
Saya lupa tepatnya kapan, akhirnya sistemnya diganti, URL yang ada banyak yang dipindah ke /v2/. OAuth juga ditambahkan. Perlu diperhatikan: setelah titik ini, saya belum memeriksa lagi apakah ada bug baru. Saya asumsikan mereka sudah menyewa pentester untuk memastikan bahwa kali ini semua baik-baik saja.
Ternyata ketika saya coba lagi sebelum posting artikel ini, sebagian besar bug yang ada ternyata belum diperbaiki. Token OAuth disimpan, tapi tidak dipergunakan di semua request berikutnya.
Bug seperti ini juga menunjukkan betapa pentingnya security di startup Anda: Andaikan ada orang yang iseng/jahat/iri, startup Anda sudah bisa gulung tikar dengan kebobolan seperti ini.

Teknis

Sekarang masuk ke teknis yang agak detail. Secara teknis bug ini mudah sekali ditemukan, mudah dieksploitasi. Agak sulit diperbaiki karena ketika server diupdate, semua client harus diupdate sekaligus. Gojek sudah banyak mengubah URL ke versi 2 dan 3, Saya hanya akan menggunakan URL versi 1, supaya nggak semua orang berusaha menghack Gojek dengan URL yang saya berikan.
Siapapun bisa mengubah pulsa driver gojek manapun, ini dilakukan dengan melakukan POST ke https://api.gojek.co.id/gojek/drivers/ dengan data baru yang ingin kita update. Selain pulsa (jumlah pendapatan driver), info-info lain juga bisa diubah. Untungnya bug update ini sudah diperbaiki di URL yang baru, walau kita tetap bisa melihat info ini.
Siapapun bisa melihat data pribadi driver dengan melakuan GET ke https://api.gojek.co.id/gojek/drivers/ID. Lucu kan kalo kita naik gojek, terus bilang: mas, anaknya mak Amah kan? titip salam dari emak. ID driver bisa dengan mudah didapatkan dari history order user. Seharusnya info yang bisa diakses user dibatasi.
Siapapun bisa mendapatkan nama user, email, no HP user lain. Selain dengan melakukan search by name/email, kita juga bisa melakukan bruteforce sekuensial mulai dari: https://api.gojek.co.id/gojek/customer/543000000
Siapapun bisa mengganti no HP, email, dan nama user lain, tanpa perlu tahu passwordnya. Bug ini masih ada dan sangat parah: kita bisa mentake over user account orang lain.
Siapapun bisa melihat order history orang lain dengan request GET ke https://api.gojek.co.id/gojek/booking/history/CUSTID.
Di bulan Agustus, Gojek mulai memiliki daftar restoran, berupa nama, lokasi, jam buka, dan sebagainya. Data-data ini pun tadinya gampang sekali diubah. Sekarang kita tetap bisa melihat data-data tesebut.

Referral

Hal pertama yang merugikan pihak gojek adalah masalah sistem referral. Sistemnya cukup sederhana: user B bisa memasukkan user ID user A sebagai pihak referrer. User B akan mendapatkan 50 ribu, dan user A akan mendapatkan 50 ribu juga ketika B naik gojek pertama kali. API request yang dikirimkan sangat sederhana:
Tidak ada verifikasi bahwa user B sudah login, dan bahwa user B yang memasukkan user A.
Masalahnya adalah: ID user yang dihasilkan berurut, user baru akan memiliki ID yang tidak jauh dari user lama. Dengan membuat skrip, kita bisa meng-assign semua user baru, supaya referalnya adalah kita.
Sekitar sebulan atau dua bulan setelah saya laporkan ini, mulai ada orang yang memanfaatkan bug ini. Mereka menawarkan isi pulsa gojek dengan harga miring. Setelah kejadian ini, Gojek mendisable account yang nilai pulsanya di atas sejuta.

Tidak sulit

Faktor-faktor yang membuat eksploitasi ini gampang adalah:
  • Gojek tidak melakukan obfuscation terhadap APK Android, jadi mudah dilihat apa saja yang dilakukan di sisi client.
  • Server sangat baik hati, tidak ada rate limiting untuk berbagai request. Bahkan ada fitur “paging”, misalnya bisa minta satu halaman berisi 100 info driver gojek, lalu kita bisa minta halaman berikutnya. Mendownload puluhan ribu driver gojek bisa dilakukan sangat cepat.
  • Penamaan API endpoint sangat konsisten (bagus), jadi mudah ditebak, misalnya jika ada findByCustomerId, maka kemungkinan ada findByEmail atau findByName.

Perbaikan

Perbaikan untuk berbagai bug tersebut sudah jelas: pertama harus ada session management. Ketika login, server akan menghasilkan session yang random. Setiap kali request sesuatu, server perlu mengecek session yang aktif. Dari session tersebut, server bisa membatasi akses.

Penutup

Berhati-hatilah menshare info Anda pada sebuah aplikasi. Ini mengingatkan saya pada serial TV CSI Cyber (yang menurut saya aktingnya sangat aneh, dan teknologinya dilebih-lebihkan), tapi topik yang diangkat cukup masuk akal dan up to date. Misalnya kisah aplikasi transport yang dihack ada di Episode Killer En Route.
Sebagai informasi: bug-bug ini sudah diketahui luas, kemungkinan besar jika Anda memakai Gojek (atau sebagai driver Gojek), info Anda sudah disalin orang lain. Semoga posting ini mendorong pihak gojek untuk segera memperbaiki layanannya, karena sepertinya jika tidak dipublish, perbaikan akan lambat dilakukan, dan fitur baru lebih diutamakan.