Экспортированная Activity
Описание
Activity — это важнейший компонент Android-приложения, представляющий один экран пользовательского интерфейса и служащий точкой взаимодействия с пользователем. В отличие от традиционных парадигм, где приложения запускаются с помощью метода main()
, система Android инициирует код в экземпляре Activity посредством вызова определённых методов жизненного цикла. Activity служит точкой входа для взаимодействия приложения с пользователем и может быть вызвана как внутренними компонентами, так и компонентами других приложений.
Чтобы объявить Activity и управлять её видимостью, необходимо добавить её в файл AndroidManifest.xml приложения:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application>
</manifest>
Одним из важных атрибутов Activity является android:exported
, который определяет, может ли Activity быть запущена компонентами других приложений. Если значение атрибута android:exported
равно true
, Activity доступна для других приложений, и они могут запускать её напрямую через Intent, указав имя класса. Если значение false
, Activity может быть запущена только компонентами того же приложения, приложениями с тем же идентификатором пользователя или привилегированными системными компонентами.
Логика значения этого атрибута по умолчанию менялась с течением времени и отличалась в зависимости от версий Android. Например, на уровне API 16 (Android 4.1.1) или ниже атрибут android:exported
по умолчанию имеет значение true
. Если этот атрибут не задан явно, существует риск того, что на некоторых устройствах будут разные значения по умолчанию. Начиная с версии API 31 (Android 12) стало обязательным явно указывать значение атрибута android:exported
. Также важно учитывать, что наличие Intent-фильтров и отсутствие явно заданного значения атрибута android:exported
автоматически делает компонент экспортируемым.
Проблема
Ситуация с разными значениями атрибута android:exported
по умолчанию может привести к непреднамеренному раскрытию внутренней Activity приложения. В результате другие приложения могут неправомерно запускать внутренние Activity, что может привести к утечке конфиденциальных данных или выполнению кода в контексте уязвимого приложения.
Кроме того, различия в значениях атрибута android:exported
по умолчанию на разных версиях Android могут привести к неконсистентному поведению приложения и создать дополнительные точки для атак. Также наличие Intent-фильтров без явного указания android:exported
может сделать Activity доступной для внешних приложений, что является потенциальной угрозой безопасности.
Рекомендации
-
Всегда явно устанавливайте атрибут
android:exported
: Явное указание атрибута исключает неопределенность и четко указывает, должны ли другие приложения иметь доступ к вашей Activity. Пример:В этом примере
android:exported="false"
гарантирует, что Activity будет доступна только компонентам того же приложения. -
Ограничьте экспортирование чувствительных Activity: Если Activity обрабатывает конфиденциальные данные или функции, которые не должны быть доступны другим приложениям, всегда устанавливайте
android:exported="false"
. Это предотвращает запуск этих Activity сторонними приложениями. -
Понимание использования экспортированных Activity: Если требуется, чтобы Activity была доступна другим приложениям, убедитесь, что все входящие Intent проверяются на корректность. Используйте атрибуты фильтров Intent для ограничения доступа и добавьте проверки данных для предотвращения неправомерного использования.
-
Будьте осторожны с Intent-фильтрами: Наличие Intent-фильтра у Activity без явно установленного
android:exported
делает эту Activity экспортируемой. Поэтому всегда явно указывайтеandroid:exported
, если используете Intent-фильтры, чтобы избежать случайного раскрытия компонентов. -
Проверка манифеста: Регулярно проверяйте файл AndroidManifest.xml на наличие неправильно установленных атрибутов
android:exported
, особенно после изменений или обновлений, чтобы удостовериться, что видимость компонентов соответствует вашим намерениям.