Register now for Android Dev Summit 2019!

Tips 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:

  • Android Application Sandbox, yang memisahkan data aplikasi dan eksekusi kode dari aplikasi lainnya.
  • Framework aplikasi dengan implementasi fungsi keamanan umum yang kuat, seperti kriptografi, izin, dan IPC aman.
  • Teknologi seperti ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD calloc, dan Linux mmap_min_addr untuk mengurangi risiko yang berkaitan dengan kesalahan umum pengelolaan memori.
  • Sistem file terenkripsi yang dapat diaktifkan untuk melindungi data di perangkat yang hilang atau dicuri.
  • 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 dalam dokumen ini. Mengikuti praktik ini sebagai kebiasaan coding umum dapat mengurangi kemungkinan timbulnya masalah keamanan secara tidak sengaja yang berdampak buruk pada pengguna Anda.

Simpan data

Permasalahan keamanan yang paling umum untuk aplikasi di Android adalah apakah data yang Anda simpan di perangkat bisa diakses oleh aplikasi lain. Ada tiga cara mendasar untuk menyimpan data di perangkat:

  • Penyimpanan internal.
  • Penyimpanan eksternal.
  • Penyedia konten.
Paragraf berikut menjelaskan masalah keamanan yang terkait disertai dengan masing-masing pendekatannya.

Menggunakan penyimpanan internal

Secara default, file yang Anda buat di penyimpanan internal hanya bisa diakses oleh aplikasi Anda. Android menerapkan perlindungan ini, dan sudah cukup untuk sebagian besar aplikasi.

Secara umum, hindari mode MODE_WORLD_WRITEABLE atau MODE_WORLD_READABLE untuk file IPC karena kedua mode tersebut tidak memberikan kemampuan untuk membatasi akses data ke aplikasi tertentu, serta tidak menyediakan kontrol format data. Jika Anda ingin berbagi data dengan proses aplikasi lain, pertimbangkan untuk menggunakan penyedia konten, yang menawarkan izin membaca dan menulis ke aplikasi lain, serta dapat memberikan izin dinamis secara kasus per kasus.

Untuk memberikan perlindungan tambahan bagi data sensitif, Anda dapat mengenkripsi file lokal menggunakan kunci yang tidak dapat diakses langsung ke aplikasi. Misalnya, Anda dapat menempatkan kunci di KeyStore dan melindunginya dengan sandi pengguna yang tidak disimpan di perangkat. Meskipun tidak melindungi data dari kerentanan level root yang dapat memantau pengguna saat memasukkan sandi, tindakan tersebut dapat memberikan perlindungan bagi perangkat yang hilang tanpa enkripsi sistem file.

Menggunakan 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 dimodifikasi oleh aplikasi apa saja.

Anda harus Melakukan validasi input saat menangani data dari penyimpanan eksternal, seperti halnya dengan data dari sumber yang tidak tepercaya. Anda sebaiknya tidak menyimpan file yang dapat dieksekusi atau file class di penyimpanan eksternal sebelum pemuatan dinamis. Jika aplikasi Anda tidak mengambil file yang dapat dieksekusi dari penyimpanan eksternal, file seharusnya ditandai dan diverifikasi secara kriptografi sebelum pemuatan dinamis.

Menggunakan 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 memberikan akses untuk aplikasi lain ke ContentProvider, tandai sebagai android:exported=false di manifes aplikasi. Atau, setel atribut android:exported ke true untuk mengizinkan aplikasi lain mengakses data yang disimpan.

Saat membuat ContentProvider yang diekspor untuk digunakan oleh aplikasi lain, Anda dapat menentukan satu izin untuk membaca dan menulis, atau menentukan izin berbeda untuk membaca dan menulis. Anda harus membatasi izin hanya untuk yang diperlukan guna menyelesaikan tugas yang ada. Perhatikan bahwa biasanya lebih mudah untuk menambahkan izin di lain waktu guna menampilkan fungsi baru dibandingkan mengambilnya dan memengaruhi pengguna yang ada.

Jika Anda menggunakan penyedia konten untuk berbagi data hanya untuk beberapa aplikasi Anda sendiri, lebih baik menggunakan atribut android:protectionLevel yang disetel ke perlindungan signature. Izin tanda tangan tidak memerlukan konfirmasi pengguna, sehingga hal tersebut akan memberikan pengalaman pengguna yang lebih baik dan akses lebih terkontrol ke data penyedia konten ketika aplikasi mengakses data yang ditandatangani dengan kunci yang sama.

Penyedia konten juga dapat memberikan lebih banyak akses terperinci dengan menyebutkan atribut android:grantUriPermissions dan menggunakan tanda FLAG_GRANT_READ_URI_PERMISSION dan FLAG_GRANT_WRITE_URI_PERMISSION di objek Intent yang mengaktifkan komponennya. Cakupan izin ini selanjutnya dapat dibatasi dengan elemen <grant-uri-permission>.

Saat mengakses penyedia konten, gunakan metode kueri yang diparameterisasi seperti query(), update(), dan delete() untuk menghindari potensi injeksi SQL dari sumber yang tidak tepercaya. Perhatikan bahwa penggunaan metode yang diparameterisasi tidak akan cukup jika argumen selection dibuat dengan menggabungkan data pengguna sebelum mengirimkannya ke metode tersebut.

Jangan salah memahami keamanan tentang 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 dengan memodifikasi satu baris hanya jika nomor telepon tersebut sudah ada. Jika data penyedia konten memiliki struktur yang bisa diprediksi, izin menulis mungkin setara dengan menyediakan izin membaca dan menulis.

Menggunakan izin

Karena Android melakukan sandbox aplikasi satu dengan lainnya, aplikasi harus dengan jelas membagikan resource dan data. Caranya yaitu dengan menyatakan izin yang dibutuhkan untuk menambahkan kapabilitas yang tidak disediakan oleh sandbox dasar, termasuk akses ke fitur perangkat seperti kamera.

Meminta izin

Anda harus meminimalkan 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. Secara umum, jangan meminta izin jika tidak diperlukan untuk menjalankan aplikasi Anda, Jika ada fitur yang tanpanya aplikasi tidak dapat dijalankan, nyatakan menggunakan elemen <uses-feature> dalam file manifes.

Akan lebih baik jika Anda merancang aplikasi dengan cara yang tidak memerlukan izin apa pun Misalnya, daripada meminta akses ke informasi perangkat untuk membuat ID unik, buatlah GUID untuk aplikasi Anda (lihat bagian tentang Menangani 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 terekspos ke aplikasi lain, seperti ContentProvider. Secara umum, Anda direkomendasikan untuk menggunakan kontrol akses selain izin yang dikonfirmasi pengguna (jika memungkinkan) karena izin tersebut dapat membingungkan pengguna. Misalnya, pertimbangkan untuk menggunakan level perlindungan tanda tangan pada izin komunikasi IPC antar aplikasi yang disediakan oleh developer tunggal.

Jangan bocorkan data yang dilindungi dengan 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.

Membuat izin

Umumnya, Anda harus mencoba menetapkan izin seminimal mungkin sembari memenuhi persyaratan keamanan. 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 harus membuat izin baru, pertimbangkan apakah Anda dapat menyelesaikan tugas dengan level perlindungan tanda tangan. Izin tanda tangan bersifat transparan bagi pengguna dan memungkinkan akses hanya oleh aplikasi yang ditandatangani developer yang sama dengan aplikasi yang melakukan pemeriksaan izin. Jika izin baru masih diperlukan, izin akan dinyatakan dalam manifes aplikasi menggunakan elemen <permission>. Aplikasi yang ingin menggunakan izin baru dapat merujuknya, dengan menambahkan elemen <uses-permission> dalam masing-masing file manifesnya. Anda juga dapat menambahkan izin secara dinamis menggunakan metode addPermission().

Jika Anda membuat izin dengan level perlindungan berbahaya, ada beberapa kerumitan yang perlu Anda pertimbangkan:

  • Izin harus memiliki string yang secara singkat menyatakan kepada pengguna tentang keputusan keamanan yang harus mereka buat.
  • String izin harus diterjemahkan 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 hal tersebut memberikan tantangan non-teknis yang besar untuk Anda sebagai developer, sekaligus membingungkan pengguna. Itulah sebabnya kami tidak merekomendasikan penggunaan level izin berbahaya.

Menggunakan 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.

Menggunakan jaringan IP

Jaringan pada 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. Anda sebaiknya menggunakan HTTPS daripada HTTP setiap kali HTTPS didukung pada server, karena perangkat seluler sering terhubung pada jaringan yang tidak aman, seperti hotspot Wi-Fi publik.

Komunikasi level soket yang dienkripsi dan diautentikasi dapat dengan mudah diimplementasikan 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. Anda sebaiknya tidak menggunakan pendekatan ini karena antarmuka ini dapat diakses oleh aplikasi lain pada perangkat. Sebagai gantinya, gunakan mekanisme IPC Android yang memungkinkan autentikasi, seperti dengan Service. Mengikat ke INADDR_ANY dapat lebih buruk daripada menggunakan loopback karena aplikasi Anda dapat menerima permintaan dari mana saja.

Pastikan Anda tidak memercayai data yang didownload dari HTTP atau protokol tidak aman lainnya, termasuk validasi input di WebView dan respons apa pun untuk intent yang dikeluarkan untuk HTTP.

Menggunakan jaringan telepon

Protokol SMS utamanya dirancang untuk komunikasi antar pengguna dan tidak sesuai untuk aplikasi yang melakukan transfer data. Karena adanya keterbatasan SMS, Anda harus menggunakan Google Cloud Messaging (GCM) dan jaringan IP untuk mengirim pesan data dari server web ke aplikasi Anda di perangkat pengguna.

Berhati-hatilah karena SMS tidak dienkripsi dan tidak diautentikasi dengan baik di jaringan atau perangkat. Khususnya, setiap penerima SMS harus mengantisipasi jika pengguna yang berbahaya mungkin telah mengirim SMS ke aplikasi Anda. Jangan mengandalkan data SMS yang tidak diautentikasi untuk melakukan perintah sensitif. Anda juga perlu mengetahui bahwa SMS dapat menjadi objek 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.

Melakukan validasi input

Validasi input yang tidak memadai adalah salah satu masalah keamanan paling umum yang memengaruhi aplikasi, apa pun platform yang digunakan. Android menawarkan langkah penanggulangan level platform yang mengurangi kemunculan masalah validasi input pada aplikasi, dan Anda harus menggunakan fitur tersebut jika memungkinkan. Perlu diingat juga bahwa pemilihan bahasa yang mudah diketik cenderung mengurangi kemungkinan masalah validasi input.

Jika Anda menggunakan kode native, data apa pun yang dibaca dari file, yang diterima melalui jaringan, atau diterima dari IPC berpotensi menimbulkan masalah keamanan. Masalah yang paling umum adalah luapan buffer, use after free, dan off-by-one error. Android menyediakan sejumlah teknologi seperti ASLR dan DEP yang mengurangi eksploitasi error tersebut, tetapi mereka tidak memecahkan 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 terkena 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 mungkin akan 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 di atas, Anda harus memastikan untuk menggunakan format data yang terstruktur dengan baik dan memverifikasi bahwa data sesuai dengan format yang diharapkan. Meskipun pemblokiran atau penggantian karakter dapat menjadi strategi efektif, teknik ini rawan mengalami error dalam pengaplikasiannya dan harus dihindari jika memungkinkan.

Menangani data pengguna

Secara umum, pendekatan terbaik untuk keamanan data pengguna adalah dengan meminimalkan penggunaan API yang mengakses data rahasia atau pribadi milik pengguna. Jika Anda memiliki akses ke data pengguna dan tidak perlu menyimpan atau mengirimnya, jangan simpan atau kirim data tersebut. Pertimbangkan apakah ada cara untuk mengimplementasikan logika aplikasi Anda 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.

Jika aplikasi Anda mengakses informasi pribadi seperti sandi atau nama pengguna, harap ingat bahwa sebagian wilayah hukum mewajibkan Anda untuk memberikan kebijakan privasi yang menjelaskan penggunaan dan penyimpanan data tersebut. Jadi, mengikuti praktik terbaik keamanan untuk meminimalkan akses ke data pengguna juga dapat menyederhanakan kepatuhan.

Anda juga harus mempertimbangkan apakah aplikasi mungkin 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. Pertimbangkan untuk menjalankan 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 Meminta Izin.

Jika GUID diperlukan, buat nomor unik yang besar, lalu simpan. Jangan gunakan ID telepon seperti nomor atau IMEI telepon, yang mungkin terkait dengan informasi pribadi. Topik ini dibahas secara lebih detail dalam Blog Developer Android.

Hati-hati saat menulis ke log di perangkat. Log Android adalah resource bersama, dan tersedia untuk aplikasi dengan izin READ_LOGS. Meskipun data log ponsel bersifat sementara dan akan terhapus saat reboot, pembuatan log yang tidak benar tentang informasi pengguna dapat secara tidak sengaja membocorkan data pengguna ke aplikasi lain. Selain tidak boleh melakukan logging PII, aplikasi produksi harus membatasi penggunaan log. Untuk mengimplementasikannya dengan mudah, gunakan tanda debug dan class Log kustom dengan level logging yang mudah dikonfigurasi.

Menggunakan WebView

Karena WebView menggunakan konten web yang dapat menyertakan HTML dan JavaScript, penggunaan yang tidak tepat dapat menimbulkan masalah keamanan web umum seperti pembuatan skrip lalu lintas (injeksi JavaScript). Android menyertakan sejumlah mekanisme untuk mengurangi ruang lingkup masalah potensial ini dengan membatasi kemampuan WebView hingga ke fungsi minimum yang diperlukan oleh aplikasi Anda.

Jika aplikasi Anda tidak secara langsung menggunakan JavaScript dalam WebView, jangan panggil setJavaScriptEnabled(). Beberapa kode contoh menggunakan metode ini, yang mungkin Anda gunakan kembali dalam aplikasi produksi, oleh karena itu, hapus panggilan metode ini jika tidak diperlukan. Secara default, WebView tidak mengeksekusi JavaScript, jadi pembuatan skrip lalu lintas situs tidak dimungkinkan.

Gunakan addJavaScriptInterface() dengan sangat hati-hati karena hal tersebut mungkin menyebabkan JavaScript menjalankan operasi yang biasanya disediakan untuk aplikasi Android. Jika Anda menggunakannya, perlihatkan addJavaScriptInterface() hanya ke halaman web yang semua inputnya dapat dipercaya. Jika input yang tidak dipercaya diizinkan, JavaScript yang tidak dipercaya mungkin dapat menjalankan metode Android dalam aplikasi Anda. Secara umum, Anda direkomendasikan untuk memperlihatkan addJavaScriptInterface() hanya untuk JavaScript yang terkandung dalam APK aplikasi Anda.

Jika aplikasi Anda mengakses data sensitif dengan WebView, Anda mungkin perlu menggunakan metode clearCache() untuk menghapus file yang disimpan secara lokal. Anda juga dapat menggunakan header sisi server, seperti no-cache untuk menunjukkan bahwa aplikasi tidak boleh melakukan cache konten tertentu.

Perangkat yang menjalankan platform sebelum Android 4.4 (API level 19) menggunakan versi webkit yang memiliki sejumlah masalah keamanan. Sebagai solusinya, jika aplikasi berjalan pada perangkat ini, harus dipastikan apakah objek WebView hanya menampilkan materi tepercaya. Untuk memastikan aplikasi Anda tidak terekspos potensi kerentanan dalam SSL, gunakan objek Provider keamanan yang dapat diupdate seperti yang dijelaskan dalam Mengupdate Penyedia Keamanan Anda untuk Melindungi dari Eksploitasi SSL. Jika aplikasi harus merender konten dari web terbuka, pertimbangkan untuk menyediakan perender Anda sendiri sehingga Anda dapat selalu mengupdatenya dengan patch keamanan terbaru.

Menangani kredensial

Untuk membuat serangan phising terlihat lebih jelas dan memperkecil kemungkinannya untuk berhasil, minimalkan frekuensi permintaan kredensial pengguna. Sebaiknya, gunakan token otorisasi dan refresh.

Jika memungkinkan, jangan menyimpan nama pengguna dan sandi di perangkat. Namun, lakukan autentikasi awal menggunakan nama pengguna dan sandi yang diberikan oleh pengguna, lalu gunakan token otorisasi khusus layanan berjangka pendek.

Layanan yang dapat diakses oleh beberapa aplikasi harus diakses menggunakan AccountManager. Jika memungkinkan, gunakan class AccountManager untuk menjalankan layanan berbasis cloud dan jangan menyimpan sandi di perangkat.

Setelah menggunakan AccountManager untuk mengambil Account, gunakan CREATOR sebelum meneruskan kredensial, sehingga Anda tidak akan meneruskan kredensial ke aplikasi yang salah.

Jika kredensial hanya digunakan oleh aplikasi yang Anda buat, Anda dapat memverifikasi aplikasi yang mengakses AccountManager menggunakan checkSignature(). Atau, jika hanya satu aplikasi yang menggunakan kredensial, Anda dapat menggunakan KeyStore untuk penyimpanan.

Menggunakan 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.

Secara umum, Anda harus tahu jenis penyedia keamanan Java Cryptography Architecture (JCA) yang digunakan software Anda. Cobalah untuk menggunakan level implementasi framework tertinggi yang sudah ada sebelumnya, yang dapat mendukung kasus penggunaan Anda. Jika berlaku, gunakan penyedia yang disediakan Google dalam urutan yang ditentukan Google. Jika Anda perlu mengambil file dari lokasi yang dikenal secara aman, HTTPS URI sederhana mungkin sudah cukup dan tidak perlu pengetahuan tentang kriptografi. Jika membutuhkan tunnel yang aman, pertimbangkan untuk menggunakan HttpsURLConnection atau SSLSocket daripada menulis protokol Anda sendiri. Jika Anda menggunakan SSLSocket, perlu diketahui bahwa SSLSocket tidak melakukan verifikasi nama host. Lihat Peringatan tentang penggunaan SSLSocket secara langsung.

Jika merasa perlu menerapkan protokol Anda sendiri, jangan implementasikan algoritme kriptografi Anda sendiri. Gunakan algoritme kriptografi yang ada, seperti implementasi AES dan RSA yang disediakan di class Cipher. Selain itu, Anda harus mengikuti 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 sifatnya 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 dihasilkan oleh KeyGenerator. Penggunaan kunci yang tidak dibuat dengan generator nomor acak yang aman dapat secara signifikan melemahkan kekuatan algoritme, dan memungkinkan serangan offline.

Jika Anda perlu menyimpan kunci untuk penggunaan berulang, gunakan mekanisme, seperti KeyStore, yang menyediakan mekanisme untuk penyimpanan jangka panjang dan pengambilan kunci kriptografis.

Menggunakan komunikasi antarproses

Beberapa aplikasi mencoba untuk mengimplementasikan IPC menggunakan teknik Linux dasar, seperti soket jaringan dan file bersama. Namun, Anda sebaiknya menggunakan fungsi sistem Android untuk IPC, seperti Intent, Binder, atau Messenger, dengan Service dan BroadcastReceiver. Mekanisme Android IPC memungkinkan Anda untuk 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 ditujukan untuk digunakan oleh aplikasi lain, setel atribut android:exported ke false di elemen manifes komponen, seperti untuk elemen <service>. Hal ini berguna untuk aplikasi yang terdiri dari beberapa proses dalam UID yang sama, atau jika Anda baru memutuskan dalam pengembangan yang sebenarnya Anda tidak ingin mengekspos fungsi 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 terpisah milik Anda yang ditandatangani dengan kunci yang sama, sebaiknya gunakan izin level signature di android:protectionLevel.

Menggunakan intent

Untuk aktivitas dan penerima siaran, intent adalah mekanisme yang lebih baik untuk IPC asinkron di Android. Bergantung pada persyaratan aplikasi, Anda dapat menggunakan sendBroadcast(), sendOrderedBroadcast(), atau intent eksplisit ke komponen aplikasi tertentu. Untuk tujuan keamanan, sebaiknya gunakan intent eksplisit.

Perhatian: Jika Anda menggunakan intent untuk mengikat ke Service, pastikan aplikasi Anda aman dengan menggunakan intent eksplisit. Menggunakan intent eksplisit 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 membuat pengecualian jika Anda memanggil bindService() dengan intent implisit.

Perlu diperhatikan, 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, Anda harus mempertimbangkan 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 untuk memanggil penerima secara langsung, daripada menaikkan siaran.

Catatan: Filter intent tidak boleh dianggap sebagai 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.

Menggunakan layanan

Service sering digunakan untuk menyediakan fungsi untuk penggunaan oleh aplikasi lain. Setiap class layanan harus memiliki pernyataan <service> yang sesuai dalam file manifesnya.

Secara default, layanan tidak diekspor dan tidak dapat dipanggil oleh aplikasi lainnya. Namun, jika Anda menambahkan filter intent ke pernyataan layanan, filter akan diekspor secara default. Sebaiknya, nyatakan atribut android:exported dengan jelas untuk memastikan atribut bekerja seperti yang diinginkan. Layanan juga dapat dilindungi menggunakan atribut android:permission. Dengan begitu, aplikasi lain perlu menyatakan elemen <uses-permission> yang sesuai dalam manifesnya agar dapat memulai, menghentikan, atau mengikat ke layanan.

Catatan: Jika aplikasi menargetkan Android 5.0 (API level 21) atau yang lebih baru, gunakan JobScheduler untuk mengeksekusi layanan di latar belakang. Untuk mengetahui informasi selengkapnya tentang JobScheduler, lihat API-reference documentation.

Layanan dapat melindungi setiap panggilan IPC ke dalamnya menggunakan izin, dengan memanggil checkCallingPermission() sebelum mengeksekusi implementasi panggilan tersebut. Sebaiknya gunakan izin deklaratif dalam manifes karena lebih tahan terhadap pengawasan.

Perhatian: Jangan mengacaukan izin klien dan server; pastikan aplikasi yang dipanggil memiliki izin yang sesuai dan verifikasi bahwa Anda memberikan izin yang sama ke aplikasi yang memanggil.

Menggunakan antarmuka binder dan messenger

Menggunakan Binder atau Messenger adalah mekanisme pilihan untuk IPC model RPC di Android. Keduanya menyediakan antarmuka dengan tampilan yang jelas dan memungkinkan autentikasi endpoint dua arah, jika diperlukan.

Sebaiknya desain antarmuka aplikasi Anda dengan cara yang tidak memerlukan pemeriksaan izin spesifik antarmuka. Objek Binder dan Messenger tidak dinyatakan dalam manifes aplikasi. Oleh karena itu, Anda tidak dapat menerapkan izin deklaratif secara langsung pada keduanya. Umumnya, objek tersebut mewarisi izin yang dinyatakan dalam manifes aplikasi untuk Service atau Activity tempat keduanya diimplementasikan. Jika Anda membuat antarmuka yang memerlukan autentikasi dan/atau kontrol akses, Anda harus menambahkan kode tersebut dengan jelas sebagai kode di antarmuka Binder atau Messenger.

Jika Anda 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, permintaan bindService() mungkin gagal jika Anda tidak memiliki izin untuk mengakses layanan yang diberikan. Jika memanggil antarmuka yang disediakan secara lokal oleh aplikasi Anda sendiri, sebaiknya gunakan metode clearCallingIdentity(), yang akan menyamarkan izin pemanggil terhadap izin aplikasi, untuk melewati pemeriksaan keamanan internal. Anda dapat memulihkan izin pemanggil di lain waktu menggunakan metode restoreCallingIdentity().

Untuk mengetahui informasi selengkapnya tentang melakukan IPC dengan layanan, lihat Layanan Terikat.

Menggunakan penerima siaran

BroadcastReceiver menangani permintaan asinkron yang diinisiasi oleh Intent.

Secara default, penerima diekspor dan dapat dipanggil oleh aplikasi lainnya. Jika BroadcastReceiver dimaksudkan untuk digunakan oleh aplikasi lain, Anda mungkin perlu menerapkan izin keamanan untuk penerima menggunakan elemen <receiver> di dalam manifes aplikasi. Hal ini mencegah aplikasi tanpa izin yang sesuai agar tidak mengirimkan intent ke BroadcastReceiver.

Memuat kode secara dinamis

Anda tidak dianjurkan untuk memuat kode dari luar APK aplikasi. Hal tersebut akan secara signifikan meningkatkan kemungkinan kerentanan aplikasi karena injeksi kode atau sabotase kode. Hal ini juga meningkatkan kompleksitas terkait pengelolaan versi dan pengujian aplikasi. Selain itu, verifikasi perilaku aplikasi juga dapat terhambat, sehingga beberapa lingkungan mungkin melarangnya.

Jika aplikasi Anda memuat kode secara dinamis, hal terpenting tentang kode yang dimuat secara dinamis adalah bahwa kode berjalan dengan izin keamanan yang sama dengan 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.

Risiko keamanan utama terkait pemuatan kode secara dinamis adalah kode harus berasal dari sumber yang dapat diverifikasi. Jika modul disertakan langsung ke dalam APK, modul tersebut tidak dapat diubah oleh aplikasi lain. Hal ini berlaku baik jika kode merupakan library native atau class yang dimuat menggunakan DexClassLoader. Berbagai aplikasi mencoba memuat kode dari lokasi yang tidak aman, seperti didownload dari jaringan melalui protokol tidak dienkripsi atau dari lokasi yang dapat ditulis oleh publik, seperti penyimpanan eksternal. Lokasi tersebut memungkinkan seseorang di jaringan untuk mengubah konten dalam pengiriman, atau aplikasi lain di perangkat pengguna untuk memodifikasi konten di perangkat.

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. Biasanya, Anda tidak perlu mengkhawatirkan masalah keamanan yang menyangkut 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 ingin 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 spesifik Android atau berbeda dari 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 level OS, sehingga Dalvik dapat saling bertukar dan menggunakan data dengan kode native di aplikasi yang sama tanpa kendala keamanan.
  • 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 gunakan pemuatan class dinamis dari sumber yang tidak diverifikasi, seperti sumber jaringan yang tidak aman atau penyimpanan eksternal, karena kode dapat dimodifikasi untuk dimasukkan ke dalam perilaku berbahaya.

Keamanan dalam kode native

Umumnya, Anda harus menggunakan Android SDK dalam pengembangan aplikasi, bukan kode native dengan Android NDK. Aplikasi yang dibuat dengan kode native akan lebih rumit, kurang ringkas, dan sering kali berisi error kerusakan memori umum, seperti luapan buffer.

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 resource yang populer adalah Secure Programming HOWTO - Creating Secure Software.

Perbedaan penting antara Android dan sebagian besar lingkungan Linux adalah Application Sandbox. Di Android, semua aplikasi berjalan di Application Sandbox, termasuk aplikasi yang ditulis dengan kode native. Di level yang paling dasar, developer yang memahami Linux perlu mengetahui bahwa setiap aplikasi dilengkapi dengan UID unik dan izin yang sangat terbatas. Hal ini dibahas secara mendetail dalam Ringkasan Keamanan Android. Anda harus memahami izin aplikasi, meskipun Anda menggunakan kode native.