Panduan keamanan

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 dan calloc, serta Linux mmap_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
Bagian berikut menjelaskan masalah keamanan yang terkait dengan masing-masing pendekatan.

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 class AccountManager untuk memanggil layanan berbasis cloud dan jangan menyimpan sandi di perangkat.
  • Setelah menggunakan AccountManager untuk mengambil Account, gunakan CREATOR 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 menggunakan checkSignatures(). Atau, jika hanya ada satu aplikasi yang menggunakan kredensial, Anda dapat menggunakan KeyStore 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.