Перейти к содержанию

Хранение данных от сторонних сервисов в открытом виде

Критичность: СРЕДНИЙ

Описание

Проблема хранения данных — одна из самых часто встречающихся в мобильных приложениях. Причем речь может идти не только об информации, непосредственно связанной с самим приложением и пользователями (пароли, пин-коды, персональные и конфиденциальные сведения), но и о данных для доступа к сторонним сервисам. Сегодня мобильные приложения для реализации своего функционала часто используют внешние сервисы, включая рассылку Push-уведомлений, хранение изображений на S3, интеграцию с различными картами, сервисами местоположения и многое-многое другое. Очень важно правильно хранить токены, используемые для этих интеграций и контролировать права, которыми эти токены обладают. Платформа Стингрей умеет не только находить токены самых различных интеграций, но и определяет их валидность и права доступа.

Рекомендации

Если в приложении обнаружен валидный токен внешнего сервиса и он обладает избыточными правами, которые позволяют совершать действия, не предназначенные для клиентского приложения, необходимо:

  1. Отозвать существующий токен с избыточными правами.
  2. Выпустить новый токен, который будет обладать только необходимыми привилегиями.
  3. Правильно хранить подобную информацию на устройстве — можно воспользоваться функционалом Android Jetpack. Библиотека безопасности Jetpack запущена в 2019 году и хорошо зарекомендовала себя — она достаточно свежая и обеспечивает баланс между надежным шифрованием и высокой производительностью.

Подключение библиотеки.

dependencies {
    ...
    implementation 'androidx.security:security-crypto:{latest-version}'
}

На Android есть система хранения ключей (Android KeyStore), которая защищает ключи от использования другими приложениями и ограничивает их попадание в память приложения. В библиотеке Jetpack Security, есть достаточно удобный класс для взаимодействия с KeyStore — MasterKeys, который позволяет создать закрытый ключ (по умолчанию используется AES256). По сути, этот класс предоставляет простые в использовании методы для создания и извлечения ключей из хранилища ключей Android.

val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
Возможны разные способы использования этой библиотеки для разных ситуаций, например можно шифровать файлы целиком или использовать функционал для шифрования данных в Shared Preferences.

Пример шифрования файлов.

val gfgKeyAlias= MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
val file = File("ANY_FILE_NAME")
val encryptedFile = EncryptedFile.Builder(
    file,
    applicationContext,
    gfgKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

encryptedFile.openFileOutput().use { outputStream ->

}

Сохранение/чтение в Shared Prefs.

val gfgKeyAlias= MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

val anySharedPrefs= EncryptedSharedPreferences.create(
    "your_name_of_shared_prefs",
    masterKeyAlias,
    applicationContext,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

val KEY_DATA = "SHARED_DATA"
val dataToSave = "Some raw values"

// storing the data
anySharedPrefs.edit()
    .putString(SHARED_DATA, someDataBound)
    .apply()

// reading
val sharedData = anySharedPrefs.getString(SHARED_DATA, "")

Ссылки

  1. https://www.geeksforgeeks.org/how-to-encrypt-data-safely-on-the-device-and-use-the-android-keystore/
  2. https://developer.android.com/topic/security/data
  3. https://medium.com/androiddevelopers/data-encryption-on-android-with-jetpack-security-e4cb0b2d2a9
  4. https://habr.com/ru/companies/redmadrobot/articles/452252/
К началу