Sebuah vulnerability berjenis Confused Deputy ditemukan di Google Messages untuk Android oleh peneliti keamanan Daniel Púa. Kerentanan ini memungkinkan aplikasi apa pun yang tidak memiliki izin READ_CONTACTS untuk membaca foto profil kontak pengguna melalui AvatarContentProvider yang diekspor oleh Google Messages. Serangan ini tidak memerlukan root access, tidak memerlukan izin khusus, dan hanya membutuhkan aplikasi yang terinstal di perangkat yang sama.
Google menandai vulnerability ini sebagai sudah diperbaiki pada 12 Juni 2026 dan kemudian memberikan reward melalui Google Mobile VRP (Vulnerability Reward Program) pada 2 Juli 2026. Meskipun demikian, dampak dari bug ini tetap signifikan karena menunjukkan bagaimana pola desain provider yang tidak aman di Android dapat membocorkan data sensitif yang seharusnya terlindungi oleh permission boundary sistem operasi.
Apa yang Terjadi?
Kerentanan ini bekerja melalui mekanisme yang dikenal sebagai Confused Deputy — sebuah konsep keamanan di mana program dengan hak akses lebih tinggi dimanipulasi oleh program dengan hak akses lebih rendah untuk melakukan sesuatu yang tidak seharusnya dilakukan. Dalam kasus ini, Google Messages memiliki izin READ_CONTACTS sementara aplikasi penyerang tidak memiliki izin tersebut. Namun, aplikasi penyerang dapat meminta Google Messages untuk membaca foto kontak atas namanya, dan Google Messages akan melakukannya menggunakan hak aksesnya sendiri.
Alur serangannya sederhana: aplikasi penyerang mengirimkan URI content://com.android.contacts/contacts/<CONTACT_ID>/photo melalui parameter m ke AvatarContentProvider milik Google Messages. Google Messages kemudian membaca foto tersebut menggunakan hak aksesnya sendiri, merender-nya sebagai PNG, dan mengembalikan byte gambar kepada aplikasi penyerang yang tidak memiliki izin. Dengan cara ini, permission boundary yang dibangun oleh Android untuk melindungi data kontak berhasil dilewati secara bersih.
Bagaimana Vulnerability Ini Ditemukan?
Daniel Púa menemukan kerentanan ini dengan melakukan inspeksi terhadap exported content provider di Google Messages. Provider yang diekspor ini adalah: content://com.google.android.apps.messaging.shared.ui.avatar.AvatarContentProvider. Provider ini tidak memerlukan izin dari pemanggil, menerima source avatar URI melalui parameter query m, dan akan mengembalikan gambar yang sudah di-render dalam format PNG.
Ketika Daniel mencoba membaca foto kontak langsung dari aplikasi yang tidak memiliki izin READ_CONTACTS, hasilnya adalah SecurityException seperti yang diharapkan. Namun, ketika URI yang sama dikirimkan melalui Google Messages provider, aplikasi penyerang berhasil menerima byte gambar. Foto kontak yang berbeda menghasilkan PNG yang berbeda, sementara contact ID yang tidak ada mengembalikan avatar fallback yang memiliki ukuran dan hash stabil — yang memungkinkan aplikasi penyerang membedakan antara foto asli dan fallback.
Kenapa Ini Lebih dari Sekadar Exported Provider?
Banyak yang mungkin mengira bahwa exported provider hanyalah masalah konfigurasi yang sepele. Namun, bug ini menunjukkan bahwa masalah sebenarnya lebih dalam dari itu. Jika provider ini hanya mengembalikan data publik milik Google Messages, bug ini akan jauh kurang menarik. Kesalahan pentingnya adalah memungkinkan exported provider untuk mendereferensikan URI content:// arbitrer yang dikontrol oleh pemanggil dengan menggunakan hak akses ambient milik Google Messages sendiri, kemudian mengembalikan byte hasil derivasi kepada pemanggil.
Untuk provider yang dikendalikan oleh permission seperti Contacts, identitas proses yang melakukan read sangatlah penting. Read langsung dari UID penyerang gagal. Read yang dilakukan oleh UID Messages berhasil. Begitu Google Messages mengonversi foto yang terlindung menjadi PNG dan menyalurkannya kembali, permission boundary yang asli sudah berhasil dilewati. Dalam hal ini, rendering gambar, resizing, caching, dan transcoding semuanya menjadi bentuk data disclosure karena sumber aslinya dilindungi oleh permission.
Dampak dan Vektor Serangan
Penyerang membutuhkan eksekusi kode sebagai aplikasi yang terinstal di perangkat Android yang sama. Tidak diperlukan root access, izin SMS, akses akun, atau izin Contacts oleh aplikasi penyerang. Ketika Google Messages memiliki akses ke Contacts, bug ini memungkinkan ekstraksi foto kontak secara diam-diam dari model permission Contacts Android. Data yang bocor terbatas pada foto, bukan seluruh record kontak, namun foto tersebut tetap merupakan data Contacts provider yang dilindungi.
Dampak praktis juga diperkuat oleh dua detail: contact ID bersifat numerik dan mudah di-scan, sehingga aplikasi penyerang dapat melakukan iterasi terhadap semua contact ID yang ada. Selain itu, respons avatar default bersifat stabil, sehingga foto asli dapat dipisahkan dari respons fallback berdasarkan ukuran atau hash. Ini memungkinkan ekstraksi massal foto kontak dari seluruh daftar kontak pengguna tanpa interaksi yang terlihat.
Analisa Retasan
Confused Deputy bug di Google Messages ini menjadi pengingat penting tentang attack surface yang sering terabaikan di ekosistem Android — yaitu exported content provider. Banyak developer Android yang menganggap exported provider sebagai fitur normal untuk interoperabilitas antar-aplikasi, padahal setiap exported provider yang menerima input dari pemanggil eksternal seharusnya memperlakukan input tersebut sebagai data yang tidak terpercaya. Dalam kasus ini, Google Messages menerima URI
content://dari aplikasi lain dan mendereferensikannya dengan hak aksesnya sendiri — sebuah pola desain yang secara fundamental tidak aman.Pola confused deputy seperti ini bukan hal baru di keamanan Android. Insiden serupa pernah terjadi dengan berbagai aplikasi Google lainnya, termasuk Gallery, Drive, dan bahkan Chrome. Setiap kali sebuah aplikasi dengan hak akses tinggi mengekspor provider yang menerima input dari luar, potensi untuk confused deputy selalu ada. Google telah menerbitkan pedoman keamanan untuk content provider, namun implementasinya di lapangan masih sering tidak mematuhi best practices tersebut.
Dari perspektif mitigasi, developer Android harus mengikuti beberapa prinsip dasar: pertama, jangan dereferensikan URI
content://yang tidak terpercaya dengan menggunakan hak akses aplikasi sendiri. Kedua, jika pemanggil eksternal perlu menyediakan URI, mintalah URI grant eksplisit atau verifikasi bahwa pemanggil asli memiliki akses ke sumber tersebut. Ketiga, pertimbangkan rendering gambar, resizing, caching, dan transcoding sebagai bentuk data disclosure jika sumber aslinya dilindungi oleh permission. Keempat, buat provider non-exported atau lindungi dengan permission internal/signature kecuali akses eksternal benar-benar diperlukan.
Sumber: Daniel Púa – Reading Contact Photos Without READ_CONTACTS (Blog DevPloit)

