Что нового в безопасности пользователей на Android: доклад с Google I/O 2024

e5c218a182b701dc20da879d6737dfde.png

Привет, меня зовут Аня, и я Android-разработчица в KTS. В этой статье разберем, какие обновления для обеспечения безопасности пользователей были представлены в докладе Safeguarding user security on Android на Google I/O, и как они отразятся на разработке. Больше про Google I/O писали здесь.

Немного вводных по 2023 году:

— к публикации не допущено более 2 миллионов приложений, нарушающих правила;

— забанено примерно 330 тысяч плохих аккаунтов;

— каждый день сканировалось около 200 миллиардов приложений в поисках вредоносного ПО;

— более 10 миллионов долларов выплачено в качестве награды за обнаружение ошибок в безопасности.

И это еще не все. Благодаря Google Play Protect обнаружено более 500 тысяч вредоносных приложений и вынесено более 3 миллионов предупреждений.

Google Play Protect может предложить просканировать приложения во время установки, если они не были проверены до этого. Это помогает Google намного быстрее отслеживать угрозы безопасности. 

Так выглядит диалоговое окно сканирования. Под пунктом «More details» спрятан вариант установки без проверки приложения

Так выглядит диалоговое окно сканирования. Под пунктом «More details» спрятан вариант установки без проверки приложения

Оглавление

Новая защита пользователей

Android помогает пользователям управлять их данными многими способами: Runtime Permission Control для запроса разрешений во время работы приложения и Privacy Dashboard, который доступен с Android 12 и позволяет видеть все выданные разрешения. В этом году к ним добавятся новые возможности для защиты данных при краже устройства или во время демонстрации экрана, также несколько других фич.

Улучшения UX во время демонстрации экрана

Когда пользователи делятся своим экраном, они могут ненамеренно показать больше информации, чем хотели. Также злоумышленники могут убедить пользователей поделиться с ними экраном в ситуациях, когда делать это на самом деле не нужно — и так использовать демонстрацию для кражи информацию.

Чтобы помочь предотвратить такие ситуации, Google по умолчанию ограничат область для демонстрации экрана одним приложением. Но возможность поделиться всем экраном останется.

Диалоговое окно с выбором области демонстрации

Диалоговое окно с выбором области демонстрации

С выбранной опцией просмотра одного приложения status-, navigation-бары и другие UI-элементы системы будут исключены из демонстрации экрана. Показываться будет только контент выбранного приложения. Подробнее про изменения в UI читайте здесь.

Изменения затронут и отображение уведомлений. Чтобы не раскрывать чувствительную информация, например, одноразовые пароли, контент уведомлений будет скрыт. Для показа содержимого уведомлений даже во время демонстрации экрана нужно предоставить публичный контент уведомления. Если публичная версия контента не предоставлена, будет отображена приватная без контента.

Во время демонстрации экрана платформа будет определять и скрывать уведомления с одноразовыми паролями. На скриншоте ниже пользователь получил уведомление с одноразовым паролем и нажал на него. Открылся экран чата. Однако, во время демонстрации экрана зритель увидит лишь пустой экран.

Слева — то, что видит пользователь. Справа — тот, кому демонстрируют экран.

Слева — то, что видит пользователь. Справа — тот, кому демонстрируют экран.

Злоумышленники могут подсмотреть одноразовые пароли с помощью приложений, у которых выдан доступ на использование Notification Listener Service. Начиная с Android 15, такие приложения будут получать уведомления с удаленным содержимым одноразового пароля.

Носимые устройства, подключаемые через Companion Device Manager, и другие приложения, которые полагаются на контент уведомлений, продолжат получать полное содержимое уведомлений. 

Защита пользователей во время кражи устройства

Google требует аутентификацию, когда кто-то пытается изменить конкретные настройки конфиденциальности. И будет блокировать воров, когда им несколько раз не удастся залогиниться в приложении или сервисе с помощью пина или биометрии.

8c3e1dd5ba3025b537e91672090e76da.png

В тот момент, когда вор попытается стащить ваш телефон, активируется новая detection-функция. Она определяет движение при краже и блокирует экран для защиты данных пользователя.

6202542aa157f123c865a278a4193585.png

Зачастую для пользователей кража устройства — шокирующая ситуация. И они не всегда помнят, как защитить данные после кражи. Так что Google добавит фичу удаленной блокировки. Благодаря ей у пользователей появится легкий способ  удаленно заблокировать устройство. Даже если они не помнят пароль от гугл-аккаунта.

5648e6fcafa613b329ef064e2f8f3e2b.png

Private Space feature

Private Space — это отдельное пространство на устройстве для приложений. В него можно установить те приложения, о которых вы хотите чтобы никто не узнал. Или приложения, к которым вы не хотите, чтобы был доступ у других людей. Это пространство может быть распространено на любые приложения. Его можно блокировать и скрывать из просмотра.

Эта опция может быть полезной для защиты конфиденциальных приложений в случае кражи устройства, случайного разоблачения, слежки.

36de8ea59e6633004c752b36f497a66a.png

Сокращение доступа к фото и видео

В прошлом году анонсировали политику, связанную с разрешениями для фото и видео. Сейчас приложения должны демонстрировать, что запрашивают широкий доступ к фото и видео, для основного сценария использования. Активно это политика начнет внедряться в августе.

Если в вашем приложении разрешения к фото или видео нужны для кастомного пикера, то Google рекомендует использовать системный Photo picker. Например, когда вы просите пользователя выбрать фото профиля.

В докладе Android Photo picker назвали лучшим решением почти для каждого приложения. Он не требует никаких разрешений, показывает облачные фотографии и альбомы из Google Photos. Его легко добавить в приложение и кастомизировать.

d62b7b7232fc44916633602aa16c3834.png

Play Integrity API

Play Integrity API поможет проверить, исходят ли действия пользователей и запросы к серверу из вашего немодифицированного приложения, установленного через Google Play и работающего на настоящем андроид-устройстве. Play Integrity API работает на всех версиях Android SDK и полностью поддерживается как на смартфонах, так и на планшетах и foldable-устройствах. Также его можно использовать и на других Android-устройствах и для ПК в Google Play Games.

Как это работает? Вы вызываете Play Integrity Api для получения integrity-токена (токена целостности) от Google. Далее передаете полученный токен на бэкенд-сервер вашего приложения. Там вы можете расшифровать токен и получить вердикт от Play Integrity. И по нему решить, доверяете ли вы тому, что запрос был сделан из вашего подлинного приложения. 

Если что-то будет не так, то можно, например, попросить пользователя подтвердить, что это действительно он. Или отказать в доступе к чувствительной информации. Подробнее о том, как подключить Play Integrity API, можно почитать по ссылке.

Пошаговая схема работы с Play Integrity API, которая описана выше

Пошаговая схема работы с Play Integrity API, которая описана выше

Многие разработчики уже используют Play Integrity API в продакшене для проверок целостности. По данным Google, они, в среднем, сталкиваются на 80% меньше с неавторизованным использованием по сравнению с незащищенными приложениями

App access risk

App access risk  — это новый integrity-вердикт (вердикт целостности). С его помощью можно проверить есть ли риск, что ваше приложение смогут контролировать другие запущенные приложения. Например, когда пользователь хочет перевести деньги. Перед выполнением этой операции, можно проверить вердикт по риску к доступу приложению. И показать диалог от Google Play с просьбой закрыть приложения, которые могут перехватить контроль. Сейчас этот вердикт доступен в публичном бета-тесте. 

Вердикт содержит информацию о валидности устройства, приложения и т.п. Выглядит как обычный json-файл. Детальнее можно почитать в доках.

{
   requestDetails: { ... }
   appIntegrity: { ... }
   deviceIntegrity: { ... }
   accountDetails: { ... }
   environmentDetails: { ... }
}

Существует несколько уровней риска доступа к приложению:

  1. Capturing response — означает, что запущены приложения, которые могут захватывать экран.

  2. Controlling response — значит, что запущены приложения, которые могут управлять устройством. Такие приложения могут как захватывать экран, так и контролировать ввод данных внутри вашего приложения.

Слева — риски. Справа — пример диалога от Google Play с просьбой закрыть приложения

Слева — риски. Справа — пример диалога от Google Play с просьбой закрыть приложения

App access risk автоматически исключает подлинные приложения, в которых используются Accessibility API и которые прошли специальный процесс ревью.

Play Protect

Play Protect сообщает  вашему приложению о том, где он был запущен и нашел ли он известные вредоносные приложения на устройстве. Если вредоносное ПО представляет особую опасность для вашего приложения или данных пользователей, вы можете проверить вердикт и попросить пользователей включить Play Protect. Либо предложить удалить опасные приложения прежде, чем продолжить выполнять действие.

Диалог включения Play Protect

Диалог включения Play Protect

Проверка недавней активности приложения

Проверка недавней активности (Recent device activity) говорит как часто ваше приложение вызывало integrity-запросы за последний час. С ее помощью можно отследить аномально высокое количество запросов — это может быть признаком атаки.

249c5b2a511820a4b91748dd33b73ed6.png

Сначала, надо проверить данные, чтобы узнать типичный уровень активности устройства для вашего приложения. После этого можно решать, что будет делать приложение, если устройство посылает слишком много integrity-запросов.

Например, если активность немного выше обычной, вы можете поставить таймаут и попросить пользователя сделать запрос позднее. Когда активность слишком высокая, можно предпринять принудительные меры защиты.

Все три нововведения доступны как в standard (стандартных), так и в classic (классических) запросах Integrity API. Стандартные API запросы были добавлены в прошлом году. Они подходят для большинства приложений и игр. С помощью них можно получить integrity-вердикт с низкой задержкой.

Integrity API report

Проанализировать отчеты Integrity API  и проверить их на аномалии можно в Play Console.

Отчет Integrity API. Выглядит довольно стандартно по сравнению с другими репортам

Отчет Integrity API. Выглядит довольно стандартно по сравнению с другими репортам

Play Integrity API доступно всем Android-разработчикам. Но у некоторых выбранных партнеров Google Play в консоли еще есть доступ к автоматической защите целостности. Это позволяет добавить защиту без необходимости интеграции с бэкендом и без дополнительной разработки.

При включенной автоматической защите Google Play автоматически добавит проверку в вашем приложении. Также будет установлена самая сильная версия защиты от несанкционированного доступа.

Изменения в Android 15

Обновление версии target SDK

Android 15 будет предотвращать установку приложений, у которых targetSdkVersion ниже 24. Но на устройствах, которые обновятся до Android 15, все приложения с target SDK ниже 24, останутся установленными.

Думаю, подробнее описывать, для чего это требуется, не стоит. Также Google говорят о том, что подобные изменения следует ожидать и в будущих версиях Android.

Safer Intent update

Неправильная обработка интетов может создать уязвимости. В Android 15 добавятся инструменты, с помощью которых разработчики смогут определять, когда интенты их приложений не совпадают с интент-фильтрами других приложений. Ключевое здесь — убедиться в том, что отправленные явные интенты соответствуют интент-фильтрам целевого компонента.

Почему это важно? Давайте рассмотрим паттерн с уязвимостью, который в Google встречали на практике.

Внутри пакета com.victim есть файл манифеста, где определены 2 broadcast receiver. InternalReceiver не является exported, т.е. его нельзя запустить из другого приложения. ExternalReceiver, наоборот, является exported.

Package: com.victim
AndroidManifest.xml


   
       
   




   
       
   

InternalReceiver обрабатывает чувствительную информацию, а в ExternalReceiver — публичную. Внутри MainActivity создадим обработчик интетов CentralizedIntentFilter.

Package: com.victim
MainActivity.kt

object CentralizedIntentHolder {
   fun handleIntent(context: Context, intent: Intent) {
       when (intent.action) {
           "PRIVATE_INTERNAL_ACTION" -> // does sensitive stuff
           "PRIVATE_EXTERNAL_ACTION" -> // does normal stuff
       }
   }
}

class InternalReceiver: BroadcastReceiver() {
   override fun onReceive(context: Context?, intent: Intent?) {
       CentralizedIntentHolder.handleIntent(context, intent)
   }
}

class ExternalReceiver : BroadcastReceiver() {
   override fun onReceive(context: Context?, intent: Intent?) {
       CentralizedIntentHandler.handleIntent(context, intent)
   }
}

Далее определим два интента. Приватный action отправит данные приватному получателю в пределах приложения, а публичный action отправит данные во внешний обработчик в другом приложении.

Злоумышленник может просто определить action интента как внутренний. И отправить такой интент во внешний компонент. Это изменение приведет к вызову внутреннего обработчика. Таким образом, атакующий успешно вызовет обработку внутреннего действия, даже несмотря на то, что InternalReceiver не был exported.

Package: com.attacker
MainActivity.kt

val intent = Intent("com.victim.PRIVATE_INTERNAL_ACTION")

intent.setClassName("com.victim", "com.victim.ExternalReceiver")

sendBroadcast(intent)

На Android 15 отслеживать такие атаки можно будет с помощью Strict Mode. Когда Strict Mode включен, несовпадения будут показаны как нарушения в логкате. По полученным данным разработчикам стоит обновить их интенты.

Strict Mode не является обязательным. На самом деле, чтобы его использовать, ваше приложение должно быть нацелено на Android 15.

Чтобы увидеть логи с нарушениями, нужно вызвать следующий метод:

fun onCreate() {
   StrictMode.setVmPolicy(VmPolicy.Builder()
       .detectUnsafeIntentLaunch()
       .build()
   )
}

Отправка интентов с action null на Android 15 больше не будет подходить ни под один из интент-фильтров.Это изменение вызвано следующим паттерном с уязвимостью.


   
       
   
//  Creating an intent with NO actions
val intent = Intent()

intent.setClassName("com.example")

// MyReceiver gets the broadcast
sendBroadcast(intent)

Broadcast receiver MyReceiver exported — в нем не определен action. Создаем интент c action null. MyReceiver получит этот интент.Многие broadcast receiver«ы в реальных приложениях не ожидают того, что intent action будет null. И при получении таких интентов падают с Null Pointer Exception.

В Android 15 в классе IntentFilter обновится метод match. Так что нуллабельный action интента система преобразует в NO_MATCH_ACTION. Это будет доступно как часть Strict Mode.

00a657245165699011044d2481899e57.png

Что касается PendingIntent«ов — их тоже нужно обрабатывать осторожно. В рамках обновления для более безопасных интентов, создатель PendingIntent будет рассматриваться как отправитель включенного в него интента, а не pending интента.

f64ece27e14030ec2b44dad8cd7eb3de.png

Запуск background activity

Запуск нежелательной вредоносной background activity находится среди самых распространенных проблем, которые нашли исследователи безопасности.

Google обновили документацию и включили в нее best practicies. Они помогут разработчикам смягчить риски, связанные с запуском background activity.

Рассмотрим некоторые уязвимые паттерны с запуском background activity:

  1. Для показа всплывающих окон, например, рекламы, background приложение запускается поверх активного foreground приложения. И ограничивает взаимодействие пользователя с устройством. 

  1. Другой тип уязвимости — tapjacking (аналог clickjacking из веба). Background приложение может частично или полностью перекрывать активное приложение. Злоумышленник обманом заставляет пользователя нажать на элемент. Но из-за наложения действие произойдет на другом.

  1. Screen phishing — это когда background приложение может показать диалог или полноэкранную activity после того, как закрыт диалог или activity активного приложения. Это позволяет фоновому приложению выдавать себя за недавно использованное foreground-приложение.

Чтобы улучшить безопасность запуска работы в фоне на Android 15, создатели PendingIntent будут блокировать запуск background activity по умолчанию. Это сделано из-за того, что система не запрещает запуск background activity. И в Google встречали случаи, когда приложение обходило запуск background activity, благодаря отправке system-creator PendingIntent.

Еще Google собирается обновить момент,   когда activity запускается в фоне. Cтек задач не перенесется в foreground, пока создателю или отправителю PendingIntent не будет разрешено запускать background activity.

Это сделано так, потому что сейчас вредоносные приложения могут получать и запускать PendingIntent. Из-за этого системная activity переносится в tag stack вредоносного приложения. Что может привести к внезапному завершению системной activity.

Activity, совпадающая с Top UID, может запускать новые activity, создавать процессы и переносить их в foreground. Когда зловредное приложение находится в foreground, оно может запустить activity приложения-жертвы поверх себя. И затем притвориться, будто оно — одно из activity приложения жертвы и было запущено им. Чтобы предотвратить такие ситуации, будет обновлено поведение для activity, совпадающей с Top UID.

И последнее: будет обновлено то, как activity завершается. Если activity в foreground, тогда пользователь может вернуться к любой последней используемой activity. И если activity не была наверху, то пользователь вернется на домашний экран. Это предотвратит взаимодействия пользователя с приложением жертвы, которое было запущено зловредным приложением.

Заключение

В докладе были рассмотрены новые возможности для защиты данных пользователей. А также изменения в Android 15, связанные с безопасностью.

Пройдемся еще раз по некоторым из best practies для обеспечения безопасности пользователя:

  1. Разработчикам следует продолжать использовать flag_secure для защиты activity с чувствительным контентом.

  2. При первой возможности используйте последнюю версию SDK в качестве target. Так вы сможете применять последние улучшения в безопасности автоматически.

  3. Проверяйте весь предложенный Play Integrity API функционал.

  4. Убедитесь, что интенты отправляются в правильный компонент и что ваше приложение поддерживает последние обновления в запуске фоновой работы.

Интересно, как будет реализовано определение кражи устройства и не будет ли ложных срабатываний на обычное вытаскивание смартфона из кармана?  

Больше про разработку на Android:

© Habrahabr.ru