Praktik terbaik keamanan aplikasi

Dengan menjadikan aplikasi Anda lebih aman, Anda membantu menjaga kepercayaan pengguna dan integritas perangkat.

Halaman ini menyajikan praktik terbaik yang memiliki dampak positif dan signifikan pada keamanan aplikasi.

Menerapkan komunikasi yang aman

Dengan mengamankan data yang dipertukarkan antara aplikasi Anda dengan aplikasi lain, atau antara aplikasi Anda dengan sebuah situs, Anda akan meningkatkan stabilitas aplikasi dan melindungi data yang Anda kirim dan terima.

Gunakan intent implisit dan penyedia konten yang tidak diekspor

Tampilkan pemilih aplikasi

Jika sebuah intent implisit dapat meluncurkan minimal dua aplikasi pada perangkat pengguna, maka tampilkan pemilih aplikasi secara eksplisit. Strategi interaksi ini memungkinkan pengguna mentransfer informasi sensitif ke aplikasi yang mereka percayai.

Kotlin

    val intent = Intent(ACTION_SEND)
    val possibleActivitiesList: List<ResolveInfo> =
            queryIntentActivities(intent, PackageManager.MATCH_ALL)

    // Verify that an activity in at least two apps on the user's device
    // can handle the intent. Otherwise, start the intent only if an app
    // on the user's device can handle the intent.
    if (possibleActivitiesList.size > 1) {

        // Create intent to show chooser.
        // Title is something similar to "Share this photo with".

        val chooser = resources.getString(R.string.chooser_title).let { title ->
            Intent.createChooser(intent, title)
        }
        startActivity(chooser)
    } else if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
    

Java

    Intent intent = new Intent(Intent.ACTION_SEND);
    List<ResolveInfo> possibleActivitiesList =
            queryIntentActivities(intent, PackageManager.MATCH_ALL);

    // Verify that an activity in at least two apps on the user's device
    // can handle the intent. Otherwise, start the intent only if an app
    // on the user's device can handle the intent.
    if (possibleActivitiesList.size() > 1) {

        // Create intent to show chooser.
        // Title is something similar to "Share this photo with".

        String title = getResources().getString(R.string.chooser_title);
        Intent chooser = Intent.createChooser(intent, title);
        startActivity(chooser);
    } else if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
    

Info terkait:

Terapkan izin berbasis tanda tangan

Saat berbagi data antara dua aplikasi yang Anda kontrol atau miliki, gunakan izin berbasis tanda tangan. Izin ini tidak mengharuskan konfirmasi pengguna dan, sebagai gantinya, memeriksa bahwa aplikasi yang mengakses data ditandatangani menggunakan kunci penandatanganan yang sama. Oleh karena itu, izin ini menawarkan pengalaman pengguna yang lebih aman dan ringkas.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp">
        <permission android:name="my_custom_permission_name"
                    android:protectionLevel="signature" />
    

Info terkait:

Larang akses ke penyedia konten aplikasi Anda

Kecuali jika bermaksud mengirimkan data dari aplikasi Anda ke aplikasi lain yang bukan milik Anda, Anda harus secara eksplisit melarang aplikasi developer lain mengakses objek ContentProvider yang dimuat aplikasi Anda. Setelan ini sangat penting jika aplikasi Anda dapat diinstal pada perangkat yang menjalankan Android 4.1.1 (API level 16) atau yang lebih rendah, karena atribut android:exported elemen <provider> secara default bernilai true pada versi Android tersebut.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp">
        <application ... >
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.example.myapp.fileprovider"
                ...
                android:exported="false">
                <!-- Place child elements of <provider> here. -->
            </provider>
            ...
        </application>
    </manifest>
    

Minta kredensial sebelum menampilkan informasi sensitif

Saat meminta kredensial dari pengguna agar mereka dapat mengakses informasi sensitif atau konten premium dalam aplikasi Anda, mintalah PIN/sandi/pola atau kredensial biometrik, seperti menggunakan pengenalan wajah atau pengenalan sidik jari.

Untuk mempelajari cara meminta kredensial biometrik lebih lanjut, lihat panduan tentang autentikasi biometrik.

Terapkan pengamanan jaringan

Bagian berikut menjelaskan cara meningkatkan keamanan jaringan aplikasi.

Gunakan traffic SSL

Jika aplikasi Anda berkomunikasi dengan server web yang memiliki sertifikat dari CA yang terkenal dan tepercaya, permintaan HTTPS-nya sangat sederhana:

Kotlin

    val url = URL("https://www.google.com")
    val urlConnection = url.openConnection() as HttpsURLConnection
    urlConnection.connect()
    urlConnection.inputStream.use {
        ...
    }
    

Java

    URL url = new URL("https://www.google.com");
    HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
    urlConnection.connect();
    InputStream in = urlConnection.getInputStream();
    

Tambahkan konfigurasi keamanan jaringan

Jika aplikasi Anda menggunakan CA baru atau kustom, Anda dapat mendeklarasikan setelan keamanan jaringan dalam file konfigurasi. Proses ini memungkinkan Anda membuat konfigurasi tanpa mengubah kode aplikasi apa pun.

Untuk menambahkan file konfigurasi keamanan ke aplikasi Anda, ikuti langkah-langkah berikut:

  1. Deklarasikan konfigurasi dalam manifes aplikasi Anda:
  2.     <manifest ... >
            <application
                android:networkSecurityConfig="@xml/network_security_config"
                ... >
                <!-- Place child elements of <application> element here. -->
            </application>
        </manifest>
        
  3. Tambahkan file resource, yang terletak di res/xml/network_security_config.xml.

    Tentukan bahwa semua traffic ke domain tertentu harus menggunakan HTTPS dengan menonaktifkan clear-text:

        <network-security-config>
            <domain-config cleartextTrafficPermitted="false">
                <domain includeSubdomains="true">secure.example.com</domain>
                ...
            </domain-config>
        </network-security-config>
        

    Selama proses pengembangan, Anda dapat menggunakan elemen <debug-overrides> untuk secara eksplisit mengizinkan sertifikat yang diinstal oleh pengguna. Elemen ini menggantikan opsi yang penting bagi keamanan Anda selama proses debug dan pengujian tanpa memengaruhi konfigurasi rilis aplikasi. Cuplikan berikut menunjukkan cara menetapkan elemen ini dalam file XML konfigurasi keamanan jaringan aplikasi Anda.

        <network-security-config>
            <debug-overrides>
                <trust-anchors>
                    <certificates src="user" />
                </trust-anchors>
            </debug-overrides>
        </network-security-config>
        

Info terkait: Konfigurasi Keamanan Jaringan

Buat pengelola kepercayaan Anda sendiri

Pemeriksa SSL Anda tidak boleh menerima setiap sertifikat. Anda mungkin perlu menyiapkan pengelola kepercayaan dan menangani semua peringatan SSL yang terjadi jika salah satu dari kondisi berikut terjadi dalam kasus penggunaan Anda:

  • Anda berkomunikasi dengan server web yang memiliki sertifikat yang ditandatangani oleh CA baru atau kustom.
  • CA itu tidak dipercayai oleh perangkat yang Anda gunakan.
  • Anda tidak dapat menggunakan konfigurasi keamanan jaringan.

Untuk mempelajari cara menyelesaikan langkah-langkah ini lebih lanjut, lihat pembahasan tentang menangani otoritas sertifikat yang tidak dikenal.

Info terkait:

Gunakan objek WebView dengan hati-hati

Jika memungkinkan, hanya muat konten yang diizinkan dalam objek WebView. Dengan kata lain, objek WebView dalam aplikasi Anda tidak boleh mengizinkan pengguna untuk menavigasi situs yang berada di luar kendali Anda.

Selain itu, sebaiknya jangan mengaktifkan dukungan antarmuka JavaScript kecuali jika Anda sepenuhnya mengontrol dan mempercayai konten dalam objek WebView.

Gunakan saluran pesan HTML

Jika aplikasi Anda harus menggunakan dukungan antarmuka JavaScript di perangkat yang menjalankan Android 6.0 (API level 23) dan yang lebih tinggi, gunakan saluran pesan HTML alih-alih evaluateJavascript() untuk berkomunikasi antara situs dan aplikasi Anda, seperti yang ditunjukkan dalam cuplikan kode berikut:

Kotlin

    val myWebView: WebView = findViewById(R.id.webview)

    // messagePorts[0] and messagePorts[1] represent the two ports.
    // They are already tangled to each other and have been started.
    val channel: Array<out WebMessagePort> = myWebView.createWebMessageChannel()

    // Create handler for channel[0] to receive messages.
    channel[0].setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {

        override fun onMessage(port: WebMessagePort, message: WebMessage) {
            Log.d(TAG, "On port $port, received this message: $message")
        }
    })

    // Send a message from channel[1] to channel[0].
    channel[1].postMessage(WebMessage("My secure message"))
    

Java

    WebView myWebView = (WebView) findViewById(R.id.webview);

    // messagePorts[0] and messagePorts[1] represent the two ports.
    // They are already tangled to each other and have been started.
    WebMessagePort[] channel = myWebView.createWebMessageChannel();

    // Create handler for channel[0] to receive messages.
    channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
        @Override
        public void onMessage(WebMessagePort port, WebMessage message) {
             Log.d(TAG, "On port " + port + ", received this message: " + message);
        }
    });

    // Send a message from channel[1] to channel[0].
    channel[1].postMessage(new WebMessage("My secure message"));
    

Info terkait:

Memberikan izin yang tepat

Aplikasi Anda sebaiknya hanya meminta izin sebanyak yang diperlukan untuk menjalankan fungsi dengan benar. Jika memungkinkan, aplikasi Anda harus melepaskan sebagian izin ini setelah tidak diperlukan lagi.

Gunakan intent untuk mengalihkan izin

Jika memungkinkan, jangan tambahkan izin ke aplikasi untuk menyelesaikan tindakan yang dapat diselesaikan pada aplikasi lain. Sebagai gantinya, gunakan intent untuk mengalihkan permintaan itu ke aplikasi lain yang sudah memiliki izin yang diperlukan.

Contoh berikut menunjukkan cara menggunakan intent untuk mengarahkan pengguna ke aplikasi kontak, bukan meminta izin READ_CONTACTS dan WRITE_CONTACTS:

Kotlin

    // Delegates the responsibility of creating the contact to a contacts app,
    // which has already been granted the appropriate WRITE_CONTACTS permission.
    Intent(Intent.ACTION_INSERT).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
    }.also { intent ->
        // Make sure that the user has a contacts app installed on their device.
        intent.resolveActivity(packageManager)?.run {
            startActivity(intent)
        }
    }
    

Java

    // Delegates the responsibility of creating the contact to a contacts app,
    // which has already been granted the appropriate WRITE_CONTACTS permission.
    Intent insertContactIntent = new Intent(Intent.ACTION_INSERT);
    insertContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);

    // Make sure that the user has a contacts app installed on their device.
    if (insertContactIntent.resolveActivity(getPackageManager()) != null) {
        startActivity(insertContactIntent);
    }
    

Selain itu, jika aplikasi Anda perlu melakukan I/O berbasis file—seperti mengakses penyimpanan atau memilih file—aplikasi tersebut tidak memerlukan izin khusus karena sistem dapat menyelesaikan operasi itu atas nama aplikasi Anda. Lebih baik lagi, setelah pengguna memilih konten di URI tertentu, aplikasi panggilan mendapat izin ke resource yang dipilih.

Info terkait:

Bagikan data dengan banyak aplikasi dengan aman

Ikuti praktik terbaik berikut untuk membagikan konten aplikasi Anda kepada aplikasi lain dengan cara yang lebih aman:

Cuplikan kode berikut menunjukkan cara menggunakan flag pemberian izin URI dan izin penyedia konten untuk menampilkan file PDF aplikasi dalam aplikasi Penampil PDF tersendiri:

Kotlin

    // Create an Intent to launch a PDF viewer for a file owned by this app.
    Intent(Intent.ACTION_VIEW).apply {
        data = Uri.parse("content://com.example/personal-info.pdf")

        // This flag gives the started app read access to the file.
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    }.also { intent ->
        // Make sure that the user has a PDF viewer app installed on their device.
        intent.resolveActivity(packageManager)?.run {
            startActivity(intent)
        }
    }
    

Java

    // Create an Intent to launch a PDF viewer for a file owned by this app.
    Intent viewPdfIntent = new Intent(Intent.ACTION_VIEW);
    viewPdfIntent.setData(Uri.parse("content://com.example/personal-info.pdf"));

    // This flag gives the started app read access to the file.
    viewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // Make sure that the user has a PDF viewer app installed on their device.
    if (viewPdfIntent.resolveActivity(getPackageManager()) != null) {
        startActivity(viewPdfIntent);
    }
    

Catatan: Aplikasi tidak tepercaya yang menargetkan Android 10 (API level 29) dan yang lebih tinggi tidak dapat memanggil exec() pada file dalam direktori utama aplikasi tersebut. Eksekusi file dari direktori utama aplikasi yang dapat ditulis ini melanggar W^X. Aplikasi hanya boleh memuat kode biner yang tersemat dalam file APK aplikasi. Selain itu, aplikasi yang menargetkan Android 10 dan yang lebih tinggi tidak dapat menjalankan modifikasi dalam-memori atas kode executable yang berasal dari file yang dibuka dengan dlopen(). Ini termasuk file objek bersama (.so) yang berisi relokasi teks.

Info terkait: android:grantUriPermissions

Menyimpan data dengan aman

Meskipun aplikasi Anda mungkin memerlukan akses ke informasi pengguna yang sensitif, pengguna akan memberi aplikasi Anda akses ke data mereka jika mereka percaya bahwa Anda akan mengamankan data itu dengan baik.

Simpan data pribadi dalam penyimpanan internal

Simpan semua data pribadi pengguna dalam penyimpanan internal perangkat, yang di-sandbox untuk setiap aplikasi. Aplikasi Anda tidak perlu meminta izin untuk melihat file ini, dan aplikasi lain tidak dapat mengaksesnya. Sebagai pengamanan tambahan, saat pengguna meng-uninstal aplikasi, perangkat akan menghapus semua file yang disimpan oleh aplikasi tersebut dalam penyimpanan internal.

Cuplikan kode berikut menunjukkan cara menulis data ke penyimpanan internal:

Kotlin

    // Creates a file with this name, or replaces an existing file
    // that has the same name. Note that the file name cannot contain
    // path separators.
    val FILE_NAME = "sensitive_info.txt"
    val fileContents = "This is some top-secret information!"
    File(filesDir, FILE_NAME).bufferedWriter().use { writer ->
        writer.write(fileContents)
    }
    

Java

    // Creates a file with this name, or replaces an existing file
    // that has the same name. Note that the file name cannot contain
    // path separators.
    final String FILE_NAME = "sensitive_info.txt";
    String fileContents = "This is some top-secret information!";
    try (BufferedWriter writer =
                 new BufferedWriter(new FileWriter(new File(getFilesDir(), FILE_NAME)))) {
        writer.write(fileContents);
    } catch (IOException e) {
        // Handle exception.
    }
    

Cuplikan kode berikut menunjukkan operasi terbalik, membaca data dari penyimpanan internal:

Kotlin

    val FILE_NAME = "sensitive_info.txt"
    val contents = File(filesDir, FILE_NAME).bufferedReader().useLines { lines ->
        lines.fold("") { working, line ->
            "$working\n$line"
        }
    }
    

Java

    final String FILE_NAME = "sensitive_info.txt";
    StringBuffer stringBuffer = new StringBuffer();
    try (BufferedReader reader =
                 new BufferedReader(new FileReader(new File(getFilesDir(), FILE_NAME)))) {

        String line = reader.readLine();
        while (line != null) {
            stringBuffer.append(line).append('\n');
            line = reader.readLine();
        }
    } catch (IOException e) {
        // Handle exception.
    }
    

Info terkait:

Gunakan penyimpanan internal dengan hati-hati

Secara default, sistem Android tidak menerapkan pembatasan keamanan pada data yang berada dalam penyimpanan eksternal, dan media penyimpanan itu sendiri tidak dijamin akan terus terhubung dengan perangkat. Oleh karena itu, Anda harus menerapkan langkah-langkah pengamanan berikut untuk memberikan akses yang aman ke informasi dalam penyimpanan eksternal.

Gunakan akses direktori terbatas

Jika aplikasi Anda hanya perlu mengakses direktori tertentu dalam penyimpanan eksternal perangkat, Anda dapat menggunakan akses direktori terbatas untuk membatasi akses aplikasi Anda ke penyimpanan eksternal perangkat. Demi kenyamanan pengguna, aplikasi Anda harus menyimpan URI akses direktori ini sehingga pengguna tidak perlu menyetujui akses ke direktori tersebut setiap kali aplikasi Anda mencoba mengaksesnya.

Catatan: Jika Anda menggunakan akses direktori terbatas pada direktori tertentu dalam penyimpanan eksternal, perlu diketahui bahwa pengguna mungkin mengeluarkan media yang berisi penyimpanan ini selagi aplikasi Anda berjalan. Anda harus menyertakan logika untuk menangani perubahan ini dengan baik ke nilai kembalian Environment.getExternalStorageState() yang disebabkan oleh perilaku pengguna ini.

Cuplikan kode berikut menggunakan akses direktori terbatas pada direktori gambar dalam penyimpanan bersama utama perangkat:

Kotlin

    private const val PICTURES_DIR_ACCESS_REQUEST_CODE = 42

    ...

    private fun accessExternalPicturesDirectory() {
        val intent: Intent = (getSystemService(Context.STORAGE_SERVICE) as StorageManager)
                .primaryStorageVolume.createAccessIntent(Environment.DIRECTORY_PICTURES)
        startActivityForResult(intent, PICTURES_DIR_ACCESS_REQUEST_CODE)
    }

    ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
        if (requestCode == PICTURES_DIR_ACCESS_REQUEST_CODE && resultCode == Activity.RESULT_OK) {

            // User approved access to scoped directory.
            if (resultData != null) {
                val picturesDirUri: Uri = resultData.data

                // Save user's approval for accessing this directory
                // in your app.
                contentResolver.takePersistableUriPermission(
                        picturesDirUri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION
                )
            }
        }
    }
    

Java

    private static final int PICTURES_DIR_ACCESS_REQUEST_CODE = 42;

    private void accessExternalPicturesDirectory() {
      StorageManager sm =
              (StorageManager) getSystemService(Context.STORAGE_SERVICE);
      StorageVolume volume = sm.getPrimaryStorageVolume();
      Intent intent =
              volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
      startActivityForResult(intent, PICTURES_DIR_ACCESS_REQUEST_CODE);
    }

    ...

    @Override
    public void onActivityResult(int requestCode, int resultCode,
            Intent resultData) {
        if (requestCode == PICTURES_DIR_ACCESS_REQUEST_CODE &&
                resultCode == Activity.RESULT_OK) {

            // User approved access to scoped directory.
            if (resultData != null) {
                Uri picturesDirUri = resultData.getData();

                // Save user's approval for accessing this directory
                // in your app.
                ContentResolver myContentResolver = getContentResolver();
                myContentResolver.takePersistableUriPermission(picturesDirUri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
        }
    }
    

Peringatan: Jangan meneruskan null ke dalam createAccessIntent() jika tidak perlu, karena nilai ini akan memberi aplikasi Anda akses ke seluruh volume yang ditemukan StorageManager untuk aplikasi Anda.

Info terkait:

Periksa validitas data

Jika aplikasi Anda menggunakan data dari penyimpanan eksternal, pastikan isi data belum rusak atau diubah. Aplikasi Anda juga harus menyertakan logika untuk menangani file yang tidak lagi dalam format yang stabil.

Contoh berikut menunjukkan izin dan logika yang memeriksa validitas file:

AndroidManifest.xml

    <manifest ... >
        <!-- Apps on devices running Android 4.4 (API level 19) or higher cannot
             access external storage outside their own "sandboxed" directory, so
             the READ_EXTERNAL_STORAGE (and WRITE_EXTERNAL_STORAGE) permissions
             aren't necessary. -->
        <uses-permission
              android:name="android.permission.READ_EXTERNAL_STORAGE"
              android:maxSdkVersion="18" />
        ...
    </manifest>

    

MyFileValidityChecker

Kotlin

    private val UNAVAILABLE_STORAGE_STATES: Set<String> =
            setOf(MEDIA_REMOVED, MEDIA_UNMOUNTED, MEDIA_BAD_REMOVAL, MEDIA_UNMOUNTABLE)
    ...
    val ringtone = File(getExternalFilesDir(DIRECTORY_RINGTONES), "my_awesome_new_ringtone.m4a")
    when {
        isExternalStorageEmulated(ringtone) -> {
            Log.e(TAG, "External storage is not present")
        }
        UNAVAILABLE_STORAGE_STATES.contains(getExternalStorageState(ringtone)) -> {
            Log.e(TAG, "External storage is not available")
        }
        else -> {
            val fis = FileInputStream(ringtone)

            // available() determines the approximate number of bytes that
            // can be read without blocking.
            val bytesAvailable: Int = fis.available()
            val fileBuffer = ByteArray(bytesAvailable)
            StringBuilder(bytesAvailable).apply {
                while (fis.read(fileBuffer) != -1) {
                    append(fileBuffer)
                }
                // Implement appropriate logic for checking a file's validity.
                checkFileValidity(this)
            }
        }
    }
    

Java

    File ringtone = new File(getExternalFilesDir(DIRECTORY_RINGTONES,
            "my_awesome_new_ringtone.m4a"));
    if (isExternalStorageEmulated(ringtone)) {
        Logger.e(TAG, "External storage is not present");
    } else if (getExternalStorageState(ringtone) == MEDIA_REMOVED
            | MEDIA_UNMOUNTED | MEDIA_BAD_REMOVAL | MEDIA_UNMOUNTABLE) {
        Logger.e(TAG, "External storage is not available");
    } else {
        FileInputStream fis = new FileInputStream(ringtone);

        // available() determines the approximate number of bytes that
        // can be read without blocking.
        int bytesAvailable = fis.available();
        StringBuilder fileContents = new StringBuilder(bytesAvailable);
        byte[] fileBuffer = new byte[bytesAvailable];
        while (fis.read(fileBuffer) != -1) {
            fileContents.append(fileBuffer);
        }

        // Implement appropriate logic for checking a file's validity.
        checkFileValidity(fileContents);
    }
    

Info terkait:

Simpan hanya data yang tidak sensitif dalam file cache

Untuk memberikan akses lebih cepat ke data aplikasi yang tidak sensitif, simpan data tersebut dalam cache perangkat. Untuk cache yang berukuran lebih dari 1 MB, gunakan getExternalCacheDir(); jika tidak, gunakan getCacheDir(). Setiap metode memberi Anda objek File yang berisi data yang di-cache aplikasi.

Cuplikan kode berikut menunjukkan cara meng-cache file yang baru saja didownload oleh aplikasi:

Kotlin

    val cacheFile = File(myDownloadedFileUri).let { fileToCache ->
        File(cacheDir.path, fileToCache.name)
    }
    

Java

    File cacheDir = getCacheDir();
    File fileToCache = new File(myDownloadedFileUri);
    String fileToCacheName = fileToCache.getName();
    File cacheFile = new File(cacheDir.getPath(), fileToCacheName);
    

Catatan: Jika Anda menggunakan getExternalCacheDir() untuk menempatkan cache aplikasi Anda di dalam penyimpanan bersama, pengguna mungkin mengeluarkan media yang berisi penyimpanan ini selagi aplikasi Anda berjalan. Anda harus menyertakan logika untuk menangani dengan baik cache yang tidak ditemukan yang disebabkan perilaku pengguna ini.

Perhatian: Tidak ada pengamanan yang diberlakukan pada file ini. Akibatnya, aplikasi apa pun yang memiliki izin WRITE_EXTERNAL_STORAGE dapat mengakses isi cache ini.

Info terkait: Menyimpan file cache

Gunakan SharedPreferences dalam mode pribadi

Saat menggunakan getSharedPreferences() untuk membuat atau mengakses objek SharedPreferences pada aplikasi Anda, gunakan MODE_PRIVATE. Dengan begitu, hanya aplikasi Anda yang dapat mengakses informasi dalam file preferensi bersama ini.

Jika Anda ingin berbagi data dengan aplikasi lain, jangan gunakan objek SharedPreferences. Sebagai gantinya, ikuti langkah-langkah yang diperlukan untuk membagikan data dengan banyak aplikasi dengan aman.

Info terkait: Menggunakan Preferensi Bersama

Menjaga agar layanan dan dependensi tetap terbaru

Sebagian besar aplikasi menggunakan library eksternal dan informasi sistem perangkat untuk menyelesaikan tugas-tugas khusus. Dengan menjaga dependensi aplikasi Anda tetap terbaru, Anda meningkatkan keamanan titik-titik komunikasi ini.

Periksa penyedia keamanan layanan Google Play

Catatan: Bagian ini hanya berlaku pada aplikasi yang menargetkan perangkat yang telah menginstal layanan Google Play.

Jika aplikasi Anda menggunakan layanan Google Play, pastikan layanan tersebut diupdate di perangkat yang menginstal aplikasi Anda. Pemeriksaan ini harus dilakukan secara asinkron, terlepas dari UI thread. Jika perangkat tidak menggunakan layanan versi terbaru, aplikasi Anda harus memicu error otorisasi.

Untuk menentukan apakah layanan Google Play di perangkat yang menginstal aplikasi Anda sudah merupakan versi terbaru atau bukan, ikuti langkah-langkah dalam panduan untuk Memperbarui Penyedia Keamanan untuk Melindungi dari Eksploitasi SSL.

Info terkait:

Update semua dependensi aplikasi

Sebelum men-deploy aplikasi Anda, pastikan semua library, SDK, dan dependensi lainnya adalah versi terbaru:

  • Untuk dependensi pihak pertama, seperti Android SDK, gunakan fitur update yang tersedia di Android Studio, seperti SDK Manager.
  • Untuk dependensi pihak ketiga, periksa situs library yang digunakan aplikasi Anda, lalu instal update dan patch keamanan apa pun yang tersedia.

Info terkait: Menambahkan Dependensi Build

Informasi selengkapnya

Untuk mempelajari lebih lanjut cara meningkatkan keamanan aplikasi Anda, pelajari referensi berikut:

Referensi lainnya

Untuk informasi selengkapnya tentang meningkatkan keamanan aplikasi Anda, pelajari referensi berikut.

Codelab

Blog