Insecure Data Stroage Part 1-4

Description : 

This is problem of Developer that to do store sensitive information 
such as Username Password into Share Preferences file is not have encode information.

How to fix :

If you whant store sensitive information There are some basic recommendations as follows.

- Store data safely.
- Store private data within internal storage.
- Store personal information into : device internal storage (sanboxed separate app).
- Your App no require request permission to see files.
- Others App can not access file is new security furture.

- When user uninstall app, device will delete all file in internal storage.

// 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!"

openFileOutput(FILE_NAME, Context.MODE_PRIVATE).use { fos ->
    fos.write(fileContents.toByteArray())
}


- Use external storage cautiously

By Default, android system not fix to use Security limitations of external storage data.
and Data Storage no confirm to connect to device. 
(External storage directory of each machine is different)

You should following Safety measures for security of data access in external stroage.


- Use scoped directory access

If your app require access specific directory that set in external storage of device.
You can use scoped directory access for limit app that will be access external storage of device.
For convenience to users, you shuold save directory access URI, 
so that users do not need to approve directory access, every time that your app try to access it.

If you use scpoed directory access with directory that specific in external storage,
user may delete files, so should have logic for control by use Environment.getExternalStorageState()
will be return value that is user behavior.



The following code snippet uses scoped directory access with the pictures directory
within a device's primary shared storage:

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
            )
        }
    }
}


Warning !! Not should send null into createAccessIntent() more than necessary
becauase will to do your app access total quantity that StorageManager find your app.


Check validity of data

If your app use data from external storage, suold make sure that contents of data no damaged
or modified your app You shuold will have logic for manage accuracy.


The following example shows the permission and logic that check a file's validity:

<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

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)
        }
    }
}



Store only non-sensitive data in cache files

For faster access non-sensitive app data should be stored in the device's cache.
For cache larger than 1MB use getExternalCacheDir() or getCacheDir()



The following code snippet shows how to cache a file that your app recently downloaded:

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



Use SharedPreferences in private mode





More Information :


Data and file storage on Android




Preferences :   // Files lost when delete app.
- Data that store that have key and value in file .xml
- Shared Preference
- Secure Preference
- EncryptedSharedPreferences

Database : in android app   // Files lost when delete app.
  - SQLiteOpenHelper
  - Room
  - SQLCipher

Shared Storage : Data that share with others app.
Such as : Media : images , audio , videos , documents   // Files no lost when delete app.
 - MediaStore API
- Content Provider for open Database for other app can query come to your app.
can be determined, such as specific app that use same keystore.


App-specific storage : Divided into 2 types

Internal Storage (Keep a little but be safe)  // Files lost when delete app.
 - getFilesDir() - File will be store into : package_name/files/
 - getCacheDir() -  File will be store into : package_name/cache/

External Storage (Store a lot of data) // Files no lost when delete app.
 - getExternalFilesDir() - File will be store into : /storage/sdcard0/Android/data/package_name/files/........
 - getExternalCacheDir()  File will be store into : /storage/sdcard0/Android/data/package_name/cache/.......


Reference : 

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

Access Control issues Part 1-3