Экспортированный Content Provider
Описание
Content Provider отвечает за предоставление данных и управление доступом к ним. Эти данные могут храниться в файловой системе, базе данных SQLite или другом постоянном хранилище, доступном приложению. С помощью Content Provider любое приложение с соответствующими разрешениями может читать или даже изменять данные, используя стандартный набор API для выполнения необходимых транзакций.
Для объявления Content Provider в приложении его необходимо добавить в файл AndroidManifest.xml, так же как это делается для Activity и других компонентов. Чтобы объявить Content Provider, добавьте элемент <provider>
как дочерний элемент <application>
:
<manifest ... >
...
<application ... >
<provider android:name=".MyContentProvider" />
...
</application>
</manifest>
Одним из важных атрибутов ContentProvider является android:exported
, который определяет, может ли ContentProvider быть доступен компонентами других приложений. Если значение атрибута равно true
, любой компонент другого приложения может получить доступ к ContentProvider. Если значение false
, только компоненты того же приложения, приложения с тем же идентификатором пользователя или привилегированные системные компоненты могут взаимодействовать с ContentProvider.
Логика значения этого атрибута по умолчанию менялась с течением времени и отличалась в зависимости от типов компонентов и версий Android. Например, на уровне API 16 (Android 4.1.1) или ниже атрибут android:exported
по умолчанию имеет значение true
. Если этот атрибут не задан явно, существует риск того, что на некоторых устройствах значения по умолчанию могут быть разными. С версии API 31 (Android 12) стало обязательным явно указывать значение атрибута android:exported
.
Проблема
Разные значения атрибута android:exported
по умолчанию могут привести к непреднамеренному раскрытию внутренних компонентов приложения. В результате другие приложения могут получить неправомерный доступ к внутренним компонентам вашего приложения, что может привести к утечке конфиденциальных данных или выполнению кода в контексте уязвимого приложения.
Если атрибут не указан явно, приложение может оказаться подверженным атакам на разных версиях Android из-за различий в значениях по умолчанию. Таким образом, отсутствие четко заданного атрибута создает неопределенность и может сделать приложение уязвимым.
Рекомендации
-
Всегда явно устанавливайте атрибут
android:exported
: Явное указание атрибута устраняет неопределенность и четко сигнализирует о вашем намерении относительно видимости компонента. Например:<provider android:name=".MyContentProvider" android:authorities="com.example.provider" android:exported="false" />
В этом примере
android:exported="false"
гарантирует, что только компоненты того же приложения смогут получить доступ к ContentProvider. -
Понимание видимости компонентов: Убедитесь, что экспортируемые компоненты должны быть доступны внешним приложениям. Если компонент не предназначен для использования другими приложениями, установите
android:exported="false"
. Это особенно важно для компонентов, которые работают с конфиденциальной информацией. -
Проверка манифеста: Регулярно проверяйте файл AndroidManifest.xml на наличие неправильно установленных атрибутов
android:exported
, особенно после обновлений, чтобы убедиться, что видимость компонентов соответствует ожиданиям.