Android memiliki fitur keamanan bawaan yang secara signifikan mengurangi frekuensi dan dampak masalah keamanan aplikasi. Sistem ini dirancang agar Anda secara khusus dapat membuat aplikasi dengan izin file dan sistem default, serta menghindari opsi keamanan yang sulit dipilih.
Fitur keamanan inti berikut membantu Anda membuat aplikasi yang aman:
- Sandbox aplikasi Android, yang memisahkan data aplikasi dan eksekusi kode dari aplikasi lainnya.
- Framework aplikasi dengan implementasi fungsi keamanan umum yang canggih, seperti kriptografi, izin, dan komunikasi antar-proses (IPC) yang aman.
- Teknologi seperti address space layout randomization (ASLR),
no-execute (NX),
ProPolice, safe_iop,
OpenBSD
dlmalloc
dancalloc
, serta Linuxmmap_min_addr
untuk mengurangi risiko yang terkait dengan error pengelolaan memori umum. - Izin yang diberikan pengguna untuk membatasi akses ke fitur sistem dan data pengguna.
- Izin yang ditetapkan aplikasi untuk mengontrol data aplikasi pada basis per-aplikasi.
Penting bagi Anda untuk memahami praktik terbaik keamanan Android pada halaman ini. Mengikuti praktik ini sebagai kebiasaan coding umum membantu Anda menghindari timbulnya masalah keamanan secara tidak sengaja yang berdampak buruk pada pengguna Anda.
Autentikasi
Autentikasi adalah prasyarat untuk banyak operasi keamanan utama. Untuk mengontrol akses ke aset yang dilindungi seperti data pengguna, fungsi aplikasi, dan resource lainnya, Anda perlu menambahkan autentikasi ke aplikasi Android Anda.
Anda dapat meningkatkan pengalaman autentikasi pengguna dengan mengintegrasikan aplikasi dengan Credential Manager. Credential Manager adalah library Android Jetpack yang menyatukan dukungan API untuk sebagian besar metode autentikasi utama, termasuk kunci sandi, sandi, dan solusi login gabungan seperti Login dengan Google.
Untuk lebih meningkatkan keamanan aplikasi Anda, sebaiknya tambahkan metode autentikasi biometrik seperti pemindaian sidik jari atau pengenalan wajah. Target yang tepat untuk menambahkan autentikasi biometrik dapat meliputi aplikasi untuk keuangan, layanan kesehatan, atau pengelolaan identitas.
Framework isi otomatis Android dapat memudahkan proses pendaftaran dan login, sehingga mengurangi tingkat error dan hambatan pengguna. Isi otomatis terintegrasi dengan pengelola sandi, sehingga pengguna dapat memilih sandi acak yang kompleks yang dapat disimpan dan digunakan dengan mudah dan aman.
Penyimpanan data
Permasalahan keamanan paling umum untuk aplikasi Android adalah apakah data yang Anda simpan di perangkat dapat diakses oleh aplikasi lain. Ada tiga cara mendasar untuk menyimpan data di perangkat:
- Penyimpanan internal
- Penyimpanan eksternal
- Penyedia konten
Penyimpanan internal
Secara default, file yang Anda buat di penyimpanan internal hanya dapat diakses oleh aplikasi Anda. Android mengimplementasikan perlindungan ini, yang cukup memadai untuk sebagian besar aplikasi.
Hindari mode MODE_WORLD_WRITEABLE
dan
MODE_WORLD_READABLE
yang tidak digunakan lagi untuk
file IPC. Mode tersebut tidak memberikan
kemampuan untuk membatasi akses data ke aplikasi tertentu, dan tidak
memberikan kontrol format data apa pun. Jika Anda ingin berbagi data dengan
proses aplikasi lain, sebaiknya gunakan
penyedia konten yang menawarkan izin membaca dan menulis ke aplikasi lain, serta dapat memberikan
izin dinamis secara kasus per kasus.
Penyimpanan eksternal
File yang dibuat di penyimpanan eksternal, seperti kartu SD, secara umum dapat dibaca dan ditulis. Jangan menyimpan informasi sensitif menggunakan penyimpanan eksternal, karena penyimpanan eksternal dapat dihapus oleh pengguna dan juga diubah oleh aplikasi apa saja.
Anda harus Melakukan validasi input saat menangani data dari penyimpanan eksternal, seperti saat menangani data dari sumber yang tidak tepercaya. Jangan menyimpan file class atau yang dapat dieksekusi di penyimpanan eksternal sebelum pemuatan dinamis. Jika aplikasi Anda mengambil file yang dapat dieksekusi dari penyimpanan eksternal, pastikan file ditandai dan diverifikasi secara kriptografi sebelum pemuatan dinamis.
Penyedia konten
Penyedia konten
menawarkan mekanisme penyimpanan terstruktur yang dapat dibatasi
hanya untuk aplikasi Anda sendiri atau diekspor untuk mengizinkan akses oleh aplikasi lainnya.
Jika tidak ingin menyediakan akses bagi
aplikasi lain ke ContentProvider
, tandai sebagai
android:exported=false
dalam manifes aplikasi. Atau, setel atribut android:exported
ke true
agar aplikasi lain dapat mengakses data yang tersimpan.
Saat membuat ContentProvider
yang diekspor untuk digunakan oleh aplikasi lain, Anda dapat menentukan satu
izin
untuk membaca dan menulis, atau menentukan izin yang berbeda untuk membaca dan menulis.
Batasi izin Anda hanya untuk izin yang
diperlukan untuk menyelesaikan tugas yang sedang dikerjakan. Perlu diingat bahwa biasanya
akan lebih mudah untuk menambahkan izin di lain waktu untuk menampilkan fungsi baru daripada meniadakannya
dan memengaruhi pengguna yang ada.
Jika Anda menggunakan penyedia konten
untuk berbagi data hanya di antara aplikasi Anda sendiri, sebaiknya gunakan
atribut android:protectionLevel
yang disetel ke perlindungan signature
.
Izin tanda tangan tidak memerlukan konfirmasi pengguna
sehingga akan memberikan pengalaman pengguna yang lebih baik dan akses yang lebih terkontrol ke
data penyedia konten saat aplikasi yang mengakses data
ditandatangani dengan
kunci yang sama.
Penyedia konten juga dapat memberikan akses yang lebih terperinci dengan mendeklarasikan atribut android:grantUriPermissions
serta menggunakan flag FLAG_GRANT_READ_URI_PERMISSION
dan FLAG_GRANT_WRITE_URI_PERMISSION
dalam
objek Intent
yang mengaktifkan komponen. Cakupan izin ini dapat dibatasi lebih lanjut oleh elemen
<grant-uri-permission>
.
Ketika mengakses penyedia konten, gunakan metode kueri berparameter seperti query()
, update()
, dan delete()
untuk menghindari potensi injeksi SQL dari sumber yang tidak tepercaya. Perlu diperhatikan bahwa penggunaan metode berparameter tidak memadai jika argumen selection
dibuat dengan menyambungkan data pengguna sebelum mengirimkannya ke metode.
Jangan salah memahami keamanan terkait izin menulis.
Izin menulis mengizinkan pernyataan SQL yang memungkinkan beberapa data untuk dikonfirmasi menggunakan klausa WHERE
kreatif dan menguraikan hasilnya. Sebagai contoh, penyerang dapat memeriksa keberadaan nomor telepon tertentu
dalam log panggilan hanya dengan mengubah satu baris kode jika nomor telepon tersebut sudah
ada. Jika data penyedia konten memiliki struktur yang dapat diprediksi, izin
menulis mungkin setara dengan menyediakan izin membaca dan menulis.
Izin
Karena Android melakukan sandbox aplikasi satu dengan lainnya, aplikasi harus secara jelas membagikan resource dan data. Caranya yaitu dengan menyatakan izin yang dibutuhkan untuk kapabilitas tambahan yang tidak disediakan oleh sandbox dasar, termasuk akses ke fitur perangkat seperti kamera.
Permintaan izin
Minimalkan jumlah izin yang diminta aplikasi Anda. Membatasi akses ke izin sensitif akan mengurangi risiko penyalahgunaan izin tersebut secara tidak sengaja, meningkatkan adopsi yang dilakukan pengguna, dan menurunkan kerentanan aplikasi Anda terhadap penyerang. Umumnya, jangan meminta izin jika tidak diperlukan untuk menjalankan aplikasi Anda. Lihat panduan untuk mengevaluasi apakah aplikasi Anda perlu menyatakan izin.
Jika memungkinkan, buat aplikasi Anda agar tidak memerlukan izin apa pun. Misalnya, daripada meminta akses ke informasi perangkat untuk membuat ID unik, Anda dapat membuat UUID untuk aplikasi (lihat bagian tentang data pengguna). Atau, daripada menggunakan penyimpanan eksternal (yang memerlukan izin), simpan data di penyimpanan internal.
Selain meminta izin, aplikasi Anda dapat menggunakan elemen <permission>
untuk melindungi IPC yang sensitif terhadap keamanan dan diekspos ke aplikasi lain,
seperti ContentProvider
.
Secara umum, sebaiknya gunakan kontrol akses
selain izin yang dikonfirmasi pengguna jika memungkinkan karena izin tersebut dapat
membingungkan pengguna. Misalnya, pertimbangkan penggunaan tingkat
perlindungan tanda tangan pada izin untuk komunikasi IPC antara aplikasi
yang disediakan oleh satu developer.
Jangan membocorkan data yang dilindungi izin. Hal ini terjadi jika aplikasi Anda mengekspos data melalui IPC yang tersedia hanya karena aplikasi memiliki izin untuk mengakses data tersebut. Klien antarmuka IPC aplikasi Anda mungkin tidak memiliki izin akses data yang sama. Detail lebih lanjut tentang frekuensi dan kemungkinan efek masalah ini disajikan dalam makalah penelitian Permission Re-Delegation: Attacks and Defenses , yang diterbitkan di USENIX.
Definisi izin
Tentukan kumpulan izin terkecil yang memenuhi persyaratan keamanan Anda. Membuat izin baru bukanlah hal biasa untuk sebagian besar aplikasi, karena izin yang ditentukan sistem mencakup banyak situasi. Jika memungkinkan, lakukan pemeriksaan akses menggunakan izin yang ada.
Jika Anda memerlukan izin baru, pertimbangkan apakah Anda dapat menyelesaikan tugas dengan tingkat perlindungan tanda tangan. Izin tanda tangan bersifat transparan bagi pengguna, dan hanya memungkinkan akses dari aplikasi yang ditandatangani oleh developer yang sama dengan aplikasi yang melakukan pemeriksaan izin.
Jika pembuatan izin baru
masih diperlukan, nyatakan dalam manifes aplikasi menggunakan
elemen
<permission>
. Aplikasi yang menggunakan izin baru tersebut dapat mereferensikannya dengan
menambahkan
elemen <uses-permission>
dalam file manifesnya. Anda juga dapat menambahkan izin
secara dinamis menggunakan
metode
addPermission()
.
Jika Anda membuat izin dengan tingkat perlindungan berbahaya, ada beberapa kerumitan yang perlu dipertimbangkan:
- Izin harus memiliki string yang secara singkat menyatakan kepada pengguna tentang keputusan keamanan yang harus mereka buat.
- String izin harus dilokalkan ke berbagai bahasa.
- Pengguna dapat memilih untuk tidak menginstal aplikasi karena adanya izin yang membingungkan atau dianggap berisiko.
- Aplikasi dapat meminta izin ketika pembuat izin belum diinstal.
Masing-masing memberikan tantangan non-teknis yang besar untuk Anda sebagai developer sekaligus juga membingungkan pengguna. Itulah sebabnya mengapa kami tidak menyarankan penggunaan tingkat izin berbahaya.
Jaringan
Transaksi jaringan secara inheren berisiko terhadap keamanan, karena melibatkan pengiriman data yang kemungkinan bersifat pribadi kepada pengguna. Orang-orang semakin sadar akan masalah privasi pada perangkat seluler, terutama ketika perangkat melakukan transaksi jaringan, sehingga sangat penting bagi aplikasi Anda untuk mengimplementasikan semua praktik terbaik guna menjaga keamanan data pengguna setiap saat.
Jaringan IP
Jaringan di Android tidak berbeda secara signifikan dari lingkungan Linux
lainnya. Pertimbangan utamanya adalah memastikan protokol
yang tepat digunakan untuk data sensitif, seperti HttpsURLConnection
untuk
traffic web yang aman. Sebaiknya gunakan HTTPS daripada HTTP setiap kali HTTPS didukung
di server, karena perangkat seluler sering terhubung pada jaringan
yang tidak aman, seperti hotspot Wi-Fi publik.
Komunikasi tingkat soket yang dienkripsi dan diautentikasi dapat
diimplementasikan dengan mudah menggunakan class
SSLSocket
. Mengingat seringnya perangkat Android terhubung ke jaringan nirkabel tidak aman
menggunakan Wi-Fi, penggunaan jaringan aman sangat direkomendasikan
untuk semua aplikasi yang berkomunikasi melalui jaringan.
Beberapa aplikasi menggunakan port jaringan localhost untuk
menangani IPC sensitif. Sebaiknya jangan gunakan pendekatan ini karena antarmuka ini
dapat diakses oleh aplikasi lain di perangkat. Sebagai gantinya, gunakan mekanisme IPC Android
yang memungkinkan autentikasi, misalnya dengan Service
.
Menautkan ke alamat IP non-spesifik INADDR_ANY
tidak lebih baik daripada menggunakan loopback, karena memungkinkan aplikasi Anda
untuk menerima permintaan dari alamat IP mana pun.
Pastikan Anda tidak
memercayai data yang didownload dari HTTP atau protokol tidak aman lainnya. Ini mencakup
validasi input dalam WebView
dan
respons apa pun pada intent yang dikeluarkan terhadap HTTP.
Jaringan telepon
Protokol Short Message Service (SMS) dirancang terutama untuk komunikasi antarpengguna dan tidak cocok untuk aplikasi yang ingin mentransfer data. Karena pembatasan SMS ini, Anda harus menggunakan Firebase Cloud Messaging (FCM) dan jaringan IP untuk mengirim pesan data dari server web ke aplikasi Anda di perangkat pengguna.
Perlu diketahui bahwa SMS tidak dienkripsi dan tidak
diautentikasi dengan baik di jaringan maupun perangkat. Khususnya, setiap penerima SMS
harus memperkirakan jika pengguna yang berbahaya mungkin telah mengirim SMS ke aplikasi Anda. Jangan
mengandalkan data SMS yang tidak diautentikasi untuk melakukan perintah sensitif.
Perlu diketahui juga bahwa SMS dapat menjadi sasaran spoofing dan/atau
intersepsi pada jaringan. Di perangkat dengan sistem operasi Android, pesan SMS
dikirim untuk tujuan siaran, sehingga pesan tersebut dapat dibaca atau ditangkap
oleh aplikasi lain yang memiliki izin
READ_SMS
.
Validasi masukan
Validasi input yang tidak memadai adalah salah satu masalah keamanan paling umum yang memengaruhi aplikasi, terlepas dari platform yang digunakan. Android menawarkan langkah penanggulangan tingkat platform yang mengurangi kemunculan masalah validasi input pada aplikasi, dan Anda sebaiknya menggunakan fitur tersebut jika memungkinkan. Selain itu, sebaiknya gunakan bahasa yang aman untuk mengurangi kemungkinan masalah validasi input.
Jika Anda menggunakan kode native, data apa pun yang dibaca dari file, diterima melalui jaringan, atau diterima dari IPC berpotensi menimbulkan masalah keamanan. Masalah yang paling umum adalah buffer overflow, penggunaan setelah tersedia, dan nonaktif karena satu error. Android menyediakan sejumlah teknologi seperti ASLR dan Data Execution Prevention (DEP) yang mengurangi dampak eksploitasi error ini, tetapi tidak mengatasi masalah yang mendasarinya. Anda dapat menghindari kerentanan ini dengan menangani pointer dan mengelola buffer secara hati-hati.
Bahasa berbasis string yang dinamis seperti JavaScript dan SQL juga dapat terpengaruh oleh masalah validasi input karena karakter escape dan injeksi skrip.
Jika Anda menggunakan data dalam kueri yang dikirim ke database SQL atau penyedia konten, injeksi SQL dapat menjadi masalah. Pertahanan terbaik adalah dengan menggunakan kueri yang diparameterisasi, seperti yang dibahas di bagian sebelumnya tentang penyedia konten. Membatasi izin ke hanya-baca atau hanya-tulis juga dapat mengurangi potensi bahaya yang berhubungan dengan injeksi SQL.
Jika tidak dapat menggunakan fitur keamanan yang dibahas pada bagian ini, Anda harus memastikan untuk menggunakan format data yang terstruktur dengan baik dan memverifikasi bahwa data sesuai dengan format yang diharapkan. Meskipun pemblokiran karakter tertentu atau mengganti karakter dapat menjadi strategi yang efektif, teknik ini rawan mengalami error dalam praktiknya dan harus dihindari jika memungkinkan.
Data pengguna
Pendekatan terbaik untuk keamanan data pengguna adalah dengan meminimalkan penggunaan API yang mengakses informasi sensitif atau pribadi. Jika Anda memiliki akses ke data pengguna, hindari penyimpanan atau pengiriman data tersebut jika memungkinkan. Pertimbangkan apakah logika aplikasi Anda dapat diimplementasikan menggunakan hash atau format data non-reversibel. Misalnya, aplikasi Anda mungkin menggunakan hash alamat email sebagai kunci utama untuk menghindari pengiriman atau penyimpanan alamat email. Hal ini mengurangi kemungkinan tereksposnya data secara tidak sengaja, serta mengurangi kemungkinan penyerang mencoba mengeksploitasi aplikasi Anda.
Lakukan autentikasi pengguna setiap kali memerlukan akses ke data pribadi dan gunakan metode autentikasi modern seperti kunci sandi dan Credential Manager. Jika aplikasi Anda perlu mengakses informasi pribadi, perlu diingat bahwa beberapa wilayah hukum mungkin mengharuskan Anda untuk memberikan kebijakan privasi yang menjelaskan penggunaan dan penyimpanan data tersebut. Ikuti praktik terbaik keamanan guna meminimalkan akses ke data pengguna untuk menyederhanakan kepatuhan.
Anda juga harus mempertimbangkan apakah aplikasi dapat secara tidak sengaja mengekspos informasi pribadi kepada pihak lain seperti komponen pihak ketiga untuk iklan atau layanan pihak ketiga yang digunakan oleh aplikasi Anda. Jangan berikan informasi pribadi jika Anda tidak tahu alasan mengapa komponen atau layanan memerlukan informasi tersebut. Secara umum, mengurangi akses aplikasi ke informasi pribadi akan mengurangi potensi masalah di area ini.
Jika aplikasi Anda memerlukan akses ke data sensitif, lakukan evaluasi apakah Anda perlu mengirimkannya ke server atau dapat menjalankan operasi pada klien. Sebaiknya jalankan semua kode menggunakan data sensitif pada klien untuk menghindari pengiriman data pengguna. Selain itu, pastikan juga bahwa Anda tidak secara tidak sengaja mengekspos data pengguna ke aplikasi lain pada perangkat melalui IPC yang terlalu permisif, file yang dapat ditulis publik, atau soket jaringan. IPC yang terlalu permisif adalah kasus khusus untuk kebocoran data yang dilindungi izin, yang dibahas di bagian Permintaan izin.
Jika ID Unik Global (GUID) diperlukan, buat nomor unik yang panjang, lalu simpan. Jangan gunakan ID telepon seperti nomor telepon atau IMEI, yang mungkin terkait dengan informasi pribadi. Topik ini dibahas secara lebih mendetail di halaman tentang praktik terbaik untuk ID unik.
Hati-hati saat menulis ke log di perangkat.
Di Android, log adalah resource bersama, dan tersedia
untuk aplikasi dengan izin READ_LOGS
.
Meskipun data log ponsel bersifat sementara dan akan dihapus saat perangkat dimulai ulang, logging
yang tidak benar atas informasi pengguna dapat secara tidak sengaja membocorkan data pengguna ke
aplikasi lain. Selain tidak boleh melakukan logging PII, Anda juga harus membatasi penggunaan log
dalam aplikasi produksi. Untuk mengimplementasikannya dengan mudah, gunakan flag debug dan class Log
khusus dengan tingkat logging yang mudah dikonfigurasi.
WebView
Karena WebView
menggunakan konten web yang mungkin menyertakan HTML
dan JavaScript,
penggunaan yang tidak tepat dapat memunculkan masalah keamanan web umum seperti
pembuatan skrip lintas situs
(injeksi JavaScript). Android menyertakan sejumlah mekanisme untuk mengurangi
cakupan masalah potensial ini dengan membatasi kemampuan
WebView
pada
fungsi minimal yang diperlukan aplikasi Anda.
Jika aplikasi Anda tidak menggunakan JavaScript secara langsung dalam WebView
,
jangan panggil
setJavaScriptEnabled()
.
Beberapa kode contoh menggunakan metode ini; jika Anda menggunakannya kembali dalam aplikasi
produksi, hapus panggilan metode ini jika tidak diperlukan. Secara default,
WebView
tidak
mengeksekusi JavaScript sehingga pembuatan skrip lintas situs tidak dimungkinkan.
Gunakan addJavaScriptInterface()
dengan
penanganan khusus karena metode ini memungkinkan JavaScript untuk memanggil operasi yang
biasanya dikhususkan bagi aplikasi Android. Jika Anda menggunakannya, hanya tunjukkan
addJavaScriptInterface()
ke
halaman web yang semua inputnya dapat dipercaya. Jika input yang tidak tepercaya diizinkan,
JavaScript yang tidak tepercaya dapat memanggil metode Android dalam aplikasi Anda. Secara umum, sebaiknya
hanya perlihatkan addJavaScriptInterface()
ke JavaScript yang terdapat dalam APK aplikasi.
Jika aplikasi Anda mengakses data sensitif dengan
WebView
, pertimbangkan untuk menggunakan
metode clearCache()
untuk menghapus file yang disimpan secara lokal. Anda juga dapat menggunakan header sisi server
seperti no-store
untuk menunjukkan bahwa aplikasi
tidak boleh melakukan cache pada konten tertentu.
Perangkat yang menjalankan platform yang lebih lama dari Android 4.4 (level API 19)
menggunakan versi webkit
yang memiliki sejumlah masalah keamanan.
Sebagai solusinya, jika aplikasi Anda berjalan di perangkat ini,
aplikasi harus mengonfirmasi bahwa objek WebView
hanya menampilkan konten
tepercaya. Untuk memastikan aplikasi Anda terhindar dari
potensi kerentanan di SSL, gunakan objek Provider
keamanan yang dapat diperbarui seperti yang dijelaskan dalam Mengupdate penyedia keamanan agar terlindung dari eksploit SSL. Jika aplikasi harus
merender konten dari web terbuka, sebaiknya sediakan perender Anda sendiri sehingga
Anda dapat selalu mengupdate-nya dengan patch keamanan terbaru.
Permintaan kredensial
Permintaan kredensial adalah vektor serangan. Berikut adalah beberapa tips untuk membantu Anda membuat permintaan kredensial di aplikasi Android dengan lebih aman.
Meminimalkan eksposur kredensial
- Hindari permintaan kredensial yang tidak perlu. Untuk membuat serangan phishing terlihat lebih jelas dan memperkecil peluang keberhasilannya, minimalkan frekuensi permintaan kredensial pengguna. Sebaiknya gunakan token otorisasi lalu muat ulang. Hanya minta informasi kredensial dalam jumlah minimum yang diperlukan untuk autentikasi dan otorisasi.
- Simpan kredensial dengan aman. Gunakan Credential Manager untuk mengaktifkan autentikasi tanpa sandi menggunakan kunci sandi atau untuk mengimplementasikan login gabungan menggunakan skema seperti Login dengan Google. Jika Anda harus menggunakan autentikasi sandi tradisional, jangan menyimpan ID pengguna dan sandi di perangkat. Sebaiknya, lakukan autentikasi awal menggunakan nama pengguna dan sandi yang diberikan pengguna, lalu gunakan token otorisasi khusus layanan berjangka pendek.
- Batasi cakupan izin. Jangan meminta izin yang luas untuk tugas yang hanya memerlukan cakupan lebih sempit.
- Batasi token akses. Gunakan operasi token dan panggilan API yang memiliki masa aktif singkat.
- Batasi frekuensi autentikasi. Autentikasi atau permintaan otorisasi yang cepat dan berurutan dapat menjadi tanda serangan brute force. Batasi frekuensi ini ke frekuensi yang wajar, tetapi tetap berikan pengalaman aplikasi yang fungsional dan mudah digunakan.
Menggunakan autentikasi yang aman
- Implementasikan kunci sandi. Aktifkan kunci sandi sebagai upgrade yang lebih aman dan mudah digunakan untuk sandi.
- Tambahkan biometrik. Tawarkan kemampuan untuk menggunakan autentikasi biometrik seperti sidik jari atau pengenalan wajah sebagai keamanan tambahan.
- Gunakan penyedia identitas gabungan. Credential Manager mendukung penyedia autentikasi gabungan seperti Login dengan Google.
- Enkripsi komunikasi Gunakan HTTPS dan teknologi serupa untuk memastikan data yang dikirimkan aplikasi Anda melalui jaringan terlindungi.
Mempraktikkan pengelolaan akun yang aman
- Hubungkan ke layanan yang dapat diakses oleh beberapa aplikasi menggunakan
AccountManager
. Jika memungkinkan, gunakan classAccountManager
untuk memanggil layanan berbasis cloud dan jangan menyimpan sandi di perangkat. - Setelah menggunakan
AccountManager
untuk mengambilAccount
, gunakanCREATOR
sebelum meneruskan kredensial apa pun sehingga Anda tidak meneruskan kredensial ke aplikasi yang salah secara tidak sengaja. - Jika kredensial hanya digunakan oleh aplikasi yang Anda buat, Anda dapat memverifikasi
aplikasi yang mengakses
AccountManager
menggunakancheckSignatures()
. Atau, jika hanya ada satu aplikasi yang menggunakan kredensial, Anda dapat menggunakanKeyStore
untuk penyimpanan.
Tetap waspada
- Pastikan kode Anda selalu yang terbaru. Pastikan Anda mengupdate kode sumber, termasuk library dan dependensi pihak ketiga, untuk mencegah kerentanan terbaru.
- Pantau aktivitas mencurigakan. Cari potensi penyalahgunaan, seperti pola penyalahgunaan otorisasi.
- Audit kode Anda. Lakukan pemeriksaan keamanan rutin terhadap codebase Anda untuk mencari potensi masalah permintaan kredensial.
Kriptografi
Selain menyediakan isolasi data, mendukung enkripsi sistem file penuh, dan menyediakan saluran komunikasi yang aman, Android juga memberikan beragam algoritme untuk melindungi data menggunakan kriptografi.
Ketahui jenis penyedia keamanan Java Cryptography Architecture (JCA) yang digunakan software Anda. Cobalah untuk menggunakan tingkat implementasi framework tertinggi yang sudah ada sebelumnya, yang dapat mendukung kasus penggunaan Anda. Jika sesuai, gunakan penyedia yang disediakan Google dalam urutan yang ditentukan Google.
Jika perlu mengambil file dengan aman dari lokasi jaringan yang diketahui, URI HTTPS
sederhana mungkin sudah memadai dan tidak mengharuskan Anda memahami kriptografi. Jika memerlukan
saluran yang aman, pertimbangkan penggunaan HttpsURLConnection
atau
SSLSocket
, bukan menulis protokol Anda sendiri. Jika Anda
menggunakan SSLSocket
, perhatikan bahwa Anda tidak melakukan verifikasi nama host. Lihat
Peringatan tentang penggunaan SSLSocket
secara langsung.
Jika merasa perlu mengimplementasikan protokol Anda sendiri, jangan
implementasikan algoritme kriptografis milik Anda. Gunakan algoritme kriptografis
yang ada, seperti implementasi AES dan RSA yang disediakan dalam
class Cipher
. Selain itu, ikuti praktik terbaik
berikut:
- Gunakan AES 256 bit untuk tujuan komersial. (Jika tidak tersedia, gunakan AES 128 bit).
- Gunakan kunci publik ukuran 224- atau 256 bit untuk kriptografi elliptic curve (EC).
- Ketahui kapan harus menggunakan mode blok CBC, CTR, atau GCM.
- Hindari penggunaan ulang IV/counter dalam mode CTR. Pastikan semuanya acak secara kriptografis.
- Saat menggunakan enkripsi, implementasikan integritas menggunakan mode CBC atau CTR dengan salah satu fungsi berikut:
- HMAC-SHA1
- HMAC-SHA-256
- HMAC-SHA-512
- Mode GCM
Gunakan generator angka acak yang aman, SecureRandom
,
untuk menginisialisasi kunci kriptografis apa pun yang dibuat oleh KeyGenerator
.
Penggunaan kunci yang tidak dibuat dengan generator angka acak
yang aman dapat secara signifikan melemahkan kekuatan algoritme, dan
memungkinkan serangan offline.
Jika perlu menyimpan kunci untuk penggunaan berulang, gunakan mekanisme seperti
KeyStore
yang
menyediakan penyimpanan jangka panjang dan pengambilan kunci
kriptografis.
Komunikasi antar-proses
Beberapa aplikasi mencoba untuk mengimplementasikan IPC menggunakan teknik Linux
tradisional, seperti soket jaringan dan file bersama. Namun, sebaiknya
gunakan fungsionalitas sistem Android untuk IPC, seperti Intent
,
Binder
, atau Messenger
dengan Service
, dan BroadcastReceiver
.
Mekanisme IPC Android memungkinkan Anda memverifikasi identitas
aplikasi yang terhubung ke IPC dan menyetel kebijakan keamanan untuk setiap mekanisme
IPC.
Banyak elemen keamanan dibagikan dalam mekanisme IPC.
Jika mekanisme IPC Anda tidak dimaksudkan untuk digunakan oleh aplikasi lain, setel
atribut android:exported
ke false
dalam elemen manifes komponen,
seperti untuk elemen
<service>
. Cara ini berguna untuk aplikasi yang terdiri dari beberapa proses
dalam UID yang sama, atau jika Anda baru membuat keputusan dalam proses pengembangan bahwa sebenarnya Anda
tidak ingin menunjukkan fungsionalitas sebagai IPC, tetapi tidak ingin menulis ulang
kodenya.
Jika IPC dapat diakses oleh aplikasi lain, Anda dapat
menerapkan kebijakan keamanan menggunakan elemen
<permission>
. Jika IPC berada di antara aplikasi milik Anda dan ditandatangani dengan kunci yang sama,
gunakan izin level signature
di android:protectionLevel
.
Intent
Untuk aktivitas dan penerima siaran, intent adalah mekanisme yang lebih baik untuk
IPC asinkron di Android.
Bergantung pada persyaratan aplikasi Anda, Anda dapat menggunakan sendBroadcast()
, sendOrderedBroadcast()
,
atau intent eksplisit untuk komponen aplikasi tertentu. Untuk tujuan keamanan,
sebaiknya gunakan intent eksplisit.
Perhatian: Jika Anda menggunakan intent untuk tertaut ke
Service
, gunakan intent
eksplisit
untuk menjaga keamanan aplikasi Anda. Menggunakan intent implisit untuk memulai layanan dapat
membahayakan keamanan, karena Anda tidak dapat memastikan layanan yang akan merespons intent tersebut,
dan pengguna tidak dapat melihat layanan yang dimulai. Mulai dari Android 5.0 (API level 21),
sistem akan
melontarkan pengecualian jika Anda memanggil bindService()
dengan intent implisit.
Perlu diperhatikan bahwa siaran yang dipesan dapat dipakai oleh penerima sehingga tidak dapat dikirimkan ke semua aplikasi. Jika mengirim intent yang harus dikirimkan ke penerima tertentu, Anda harus menggunakan intent eksplisit yang menyatakan nama penerima.
Pengirim intent dapat memverifikasi bahwa penerima memiliki izin dengan menetapkan izin yang bukan null dengan panggilan metode. Hanya aplikasi dengan izin tersebut yang akan menerima intent. Jika data dalam intent siaran bersifat sensitif, pertimbangkan penerapan izin guna memastikan agar aplikasi berbahaya tidak dapat mendaftar untuk menerima pesan tersebut tanpa izin yang sesuai. Dalam situasi seperti itu, Anda juga dapat mempertimbangkan pemanggilan penerima secara langsung, daripada menaikkan siaran.
Catatan: Filter intent bukanlah fitur keamanan. Komponen dapat dipanggil dengan intent eksplisit dan mungkin tidak memiliki data yang sesuai dengan filter intent. Untuk mengonfirmasi format yang benar bagi penerima, layanan, atau aktivitas yang dipanggil, lakukan validasi input di dalam penerima intent Anda.
Layanan
Service
sering kali digunakan untuk menyediakan fungsi yang perlu digunakan oleh
aplikasi lain. Setiap class layanan harus memiliki deklarasi <service>
yang sesuai dalam
file manifesnya.
Secara default, layanan tidak diekspor dan tidak dapat dipanggil oleh
aplikasi lain. Namun, jika Anda menambahkan filter intent ke deklarasi layanan, pengeksporan akan dilakukan
secara default. Sangat baik jika Anda secara eksplisit menyatakan atribut android:exported
untuk memastikan perilakunya sesuai dengan yang Anda inginkan.
Layanan juga dapat dilindungi menggunakan atribut
android:permission
. Dengan cara ini, aplikasi lain harus menyatakan
elemen <uses-permission>
yang sesuai dalam manifesnya agar
dapat memulai, menghentikan, atau mengikat layanan.
Catatan: Jika aplikasi Anda menargetkan Android 5.0 (API level 21) atau yang lebih tinggi,
sebaiknya gunakan JobScheduler
untuk menjalankan layanan
latar belakang.
Layanan bisa melindungi setiap panggilan IPC yang dibuat dengan izin. Hal ini dilakukan dengan
memanggil checkCallingPermission()
sebelum menjalankan
implementasi panggilan. Kami menyarankan untuk menggunakan
izin deklaratif dalam manifes, karena mengurangi kerawanan terhadap
kesalahan.
Perhatian: Jangan salah membedakan izin klien dan server; pastikan aplikasi yang dipanggil memiliki izin yang sesuai dan verifikasi bahwa Anda memberikan izin yang sama ke aplikasi yang memanggil.
Antarmuka Binder dan Messenger
Menggunakan Binder
atau Messenger
adalah
mekanisme yang dipilih untuk IPC bergaya RPC di Android. Keduanya menyediakan antarmuka
yang jelas, yang memungkinkan autentikasi endpoint dua arah jika diperlukan.
Sebaiknya desain antarmuka aplikasi Anda sedemikian rupa agar tidak memerlukan
pemeriksaan izin khusus antarmuka. Objek Binder
dan
Messenger
tidak dinyatakan dalam
manifes aplikasi sehingga Anda tidak dapat menerapkan izin deklaratif
secara langsung pada keduanya. Objek tersebut umumnya mewarisi izin yang dinyatakan dalam
manifes aplikasi untuk Service
atau Activity
tempatnya
diimplementasikan. Jika akan membuat antarmuka yang memerlukan autentikasi
dan/atau kontrol akses, Anda harus menambahkan kontrol tersebut secara eksplisit
sebagai kode dalam antarmuka Binder
atau
Messenger
.
Jika akan menyediakan antarmuka yang memerlukan kontrol akses, gunakan checkCallingPermission()
untuk memverifikasi apakah
pemanggil memiliki izin yang diperlukan. Tindakan ini khususnya perlu dilakukan
sebelum mengakses layanan atas nama pemanggil, karena identitas aplikasi Anda
akan diteruskan ke antarmuka lain. Jika Anda memanggil antarmuka yang disediakan
oleh Service
, pemanggilan bindService()
dapat gagal jika Anda tidak memiliki izin untuk mengakses layanan yang diberikan.
Jika Anda perlu mengizinkan proses eksternal untuk berinteraksi dengan aplikasi tetapi tidak memiliki
izin yang diperlukan untuk melakukannya, Anda dapat menggunakan
metode clearCallingIdentity()
. Metode ini melakukan panggilan ke antarmuka aplikasi seakan-akan aplikasi Anda melakukan panggilan itu sendiri, bukan melalui pemanggil eksternal.
Anda dapat memulihkan izin pemanggil nanti dengan
metode
restoreCallingIdentity()
.
Untuk mengetahui informasi selengkapnya tentang melakukan IPC dengan layanan, lihat Layanan Terikat.
Penerima siaran
BroadcastReceiver
menangani permintaan asinkron yang diinisiasi oleh
Intent
.
Secara default, penerima diekspor dan dapat dipanggil oleh aplikasi
lain. Jika BroadcastReceiver
dimaksudkan untuk digunakan oleh aplikasi lain, Anda
mungkin perlu menerapkan izin keamanan kepada penerima menggunakan elemen
<receiver>
dalam manifes aplikasi. Cara
ini akan mencegah pengiriman intent ke
BroadcastReceiver
oleh aplikasi yang tidak memiliki izin yang sesuai.
Keamanan dengan kode yang dimuat secara dinamis
Kami sangat tidak menyarankan pemuatan kode selain dari APK aplikasi Anda. Cara ini akan secara signifikan meningkatkan risiko penyerangan terhadap aplikasi karena injeksi kode atau sabotase kode. Ini juga menambah kerumitan pengelolaan versi dan pengujian aplikasi—dan bisa membuat verifikasi perilaku aplikasi tidak mungkin dilakukan, sehingga mungkin dilarang di beberapa lingkungan.
Jika aplikasi Anda memuat kode secara dinamis, hal terpenting untuk diingat adalah kode yang dimuat secara dinamis berjalan dengan izin keamanan yang sama seperti APK aplikasi. Pengguna membuat keputusan untuk menginstal aplikasi berdasarkan identitas Anda, dan mengharapkan Anda untuk menyediakan setiap kode yang berjalan di dalam aplikasi, termasuk kode yang dimuat secara dinamis.
Beberapa aplikasi
yang mencoba memuat kode dari lokasi yang tidak aman, seperti didownload dari
jaringan melalui protokol tidak terenkripsi atau dari lokasi yang dapat ditulis oleh publik, seperti
penyimpanan eksternal. Lokasi tersebut memungkinkan seseorang di jaringan mengubah
konten dalam pengiriman atau aplikasi lain di perangkat pengguna untuk mengubah
konten di perangkat. Di sisi lain, modul yang disertakan
langsung dalam APK Anda tidak dapat diubah oleh aplikasi lain.
Hal ini akan tetap berlaku baik jika kodenya berupa library native atau class yang dimuat menggunakan
DexClassLoader
.
Keamanan dalam mesin virtual
Dalvik adalah mesin virtual (VM) waktu proses Android. Dalvik secara khusus dibuat untuk Android, tetapi berbagai kekhawatiran terkait kode aman di mesin virtual lainnya juga berlaku untuk Android. Umumnya, Anda tidak perlu mengkhawatirkan masalah keamanan yang berkaitan dengan mesin virtual. Aplikasi Anda berjalan di lingkungan sandbox yang aman, sehingga proses lain pada sistem tidak dapat mengakses kode atau data pribadi Anda.
Jika Anda tertarik mempelajari keamanan mesin virtual lebih lanjut, pahami beberapa literatur yang ada pada topik ini. Dua contoh referensi yang populer antara lain:
Dokumen ini berfokus pada area khusus Android atau area yang berbeda dengan lingkungan VM lainnya. Untuk developer yang berpengalaman dengan pemrograman VM di lingkungan lain, ada dua persoalan umum yang mungkin berbeda tentang penulisan aplikasi untuk Android:
- Beberapa mesin virtual, seperti JVM atau .NET runtime, berfungsi sebagai batasan keamanan, yang mengisolasi kode dari kemampuan sistem operasi yang mendasarinya. Di Android, VM Dalvik bukanlah batasan keamanan, sandbox aplikasinya diimplementasikan di tingkat OS, sehingga Dalvik dapat saling bertukar dan menggunakan data dengan kode native di aplikasi yang sama tanpa kendala keamanan apa pun.
- Dengan keterbatasan penyimpanan di perangkat seluler, sering kali developer ingin membuat aplikasi modular dan menggunakan pemuatan class dinamis. Saat melakukannya, pertimbangkan kedua sumber tempat Anda mengambil logika aplikasi dan tempat Anda menyimpannya secara lokal. Jangan menggunakan pemuatan class dinamis dari sumber yang tidak diverifikasi, seperti sumber jaringan yang tidak aman atau penyimpanan eksternal, karena kode dapat diubah agar menyertakan perilaku berbahaya.
Keamanan dalam kode native
Umumnya, sebaiknya gunakan Android SDK untuk pengembangan aplikasi, bukan kode native dengan Android NDK. Aplikasi yang dibuat dengan kode native akan lebih rumit, kurang ringkas, dan sering kali memiliki error kerusakan memori umum, seperti buffer overflow.
Android dibuat menggunakan kernel Linux. Oleh karena itu, memahami praktik terbaik keamanan pengembangan Linux sangat berguna jika Anda menggunakan kode native. Praktik keamanan Linux tidak termasuk dalam cakupan dokumen ini, tetapi salah satu referensi yang populer adalah Secure Programming HOWTO - Creating Secure Software.
Perbedaan penting antara Android dan sebagian besar lingkungan Linux terletak pada sandbox aplikasi. Di Android, semua aplikasi berjalan di sandbox aplikasi, termasuk aplikasi yang ditulis dengan kode native. Pertimbangan terbaik bagi developer yang sudah terbiasa dengan Linux adalah mengetahui bahwa setiap aplikasi diberi User Identifier (UID) unik dengan izin yang sangat terbatas. Hal ini dibahas secara mendetail dalam Ringkasan Keamanan Android, dan Anda harus sudah memahami izin aplikasi meskipun menggunakan kode native.