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

search

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.

ceo

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.

Twitter: @yohanes

72 thoughts on “Bug Gojek (Agustus 2015)”

  1. Kita tidak bisa hanya menyalahkan dari sisi programmer saja, boleh jadi kesejahteraan sang programmer tersebut masih berbilang minim, jadi beliau “ogah2an” buat memperbaiki bug tersebut. Buktinya, TS yg udah nemu bug yg paling riskan, dan sangat berbahaya buat management pun tak dpt apresiasi yg cukup. Entah salah siapa saya juga gak tau..

  2. Halo Mas,

    1) Saya *dari kemaren2* masih belom ngerti flownya Oauth seperti apa. Bayangan saya sih, ala twitter. Yang modelnya ada “allow app access” gitu. Padahal hal itu mau saya remove, cuman belom ada bayangan gimana implementnya. Saya sekedar test udah bisa bikin token tapi belom tau cara mengaitkan tokennya ke request, belom lagi itu belom termasuk mengaitkan token dengan usernya.

    2) Kalau session yg dimaksud itu apa ya? Apakah semacam token? Soalnya kan bukan browser (mobile apps), jadi $_SESSION pastinya ga bisa diakses.

    Saya sendiri juga sedang membuat mobile apps yang similar, tapi based on user token. Ketika user login, server bikin key yg kemudian dikasih ke mobile apps (generationnya juga simpel, dari md5 doang dicampur value lain).

    Di server juga ada crontab permenit yang sifatnya ngebuang key tsb dari database bila user pemilik access token tsb gak aktif dalam waktu 2 jam (iya, kedengarannya aneh, tapi terus terang saya juga buta arah). Apakah ini saja cukup?

    Makasih mas atas ilmunya.

    1. Coba jawab, soal token saya pernah coba di framework php, namanya panique/huge ada di github. Disitu ada fungsi bawaan token csrf untuk menghandle ddos attack. Alurnya kira2 seperti ini
      User login kemudian secara otomatis membuat token baru yg disimpan di dalam db. Kemudian token dipanggil dan disimpan lagi di dalam session, dan selanjutnya token itu sebagai authentikasi untuk melakukan post ke db.
      Jika token tidak sesuai dan tetap dilakukan force pada db, mksudnya ddos maka aplikasi pada server akan logout dan kembali ke login. Dan jika user termasuk dlm db, selanjutnya akan di suspend.
      Selain token diperlukan sql command perlu juga di perbaiki, jika tidak menggunakan storeprocedure. Sql command sebaiknya menggunakan pdo dan dalam actionnya menggunakan catch try, juga jangan lupa menggunakan sprintf pada commandnya, untuk menghindari attack dari char yg tidak perlu pada sql command.
      Mungkin itu bisa sedikit membantu.

  3. Harusnya api key itu memang menampilkan format json tanpa ada authentikasi, tapi info-info terkait dengan data user ditampilkan beberapa saja, hal yg umum saja. Kemudian fungsi post diberikan token dan session, misalnya menggunakan OAuth sebagai third party, dan session login dan token tersebut disamakan dengan token dan session di db, sehingga jika tidak ada kesesuaian maka aplikasi akan force close.

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.