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

Экспортированный Content Provider

Критичность: ИНФО
Способ обнаружения: SAST, APK

Описание

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.

Для элемента <provider> логика значения этого атрибута по умолчанию отличается от других компонентов. Сам атрибут android:exported для <provider> появился только на уровне API 17 (Android 4.2). Поэтому:

  • на устройствах с API 16 (Android 4.1) и ниже атрибут не поддерживается, и ContentProvider ведёт себя так, как будто android:exported="true" (то есть доступен другим приложениям);
  • если приложение собрано с targetSdkVersion 17 или выше, то на устройствах с API 17+ значением по умолчанию является false (то есть ContentProvider не экспортируется, если не указано обратное).

Из-за этой разницы поведение незаданного явно атрибута зависит от версии Android и targetSdkVersion, поэтому полагаться на значение по умолчанию небезопасно. С версии API 31 (Android 12) для компонентов с intent-фильтрами явное указание android:exported стало обязательным; для ContentProvider в любом случае рекомендуется указывать атрибут явно.

Проблема

Разные значения атрибута android:exported по умолчанию могут привести к непреднамеренному раскрытию внутренних компонентов приложения. В результате другие приложения могут получить неправомерный доступ к внутренним компонентам вашего приложения, что может привести к утечке конфиденциальных данных или выполнению кода в контексте уязвимого приложения.

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

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

  1. Всегда явно устанавливайте атрибут android:exported: Явное указание атрибута устраняет неопределенность и четко сигнализирует о вашем намерении относительно видимости компонента. Например:

    <provider
        android:name=".MyContentProvider"
        android:authorities="com.example.provider"
        android:exported="false" />
    

    В этом примере android:exported="false" гарантирует, что только компоненты того же приложения смогут получить доступ к ContentProvider.

  2. Понимание видимости компонентов: Убедитесь, что экспортируемые компоненты должны быть доступны внешним приложениям. Если компонент не предназначен для использования другими приложениями, установите android:exported="false". Это особенно важно для компонентов, которые работают с конфиденциальной информацией.

  3. Проверка манифеста: Регулярно проверяйте файл AndroidManifest.xml на наличие неправильно установленных атрибутов android:exported, особенно после обновлений, чтобы убедиться, что видимость компонентов соответствует ожиданиям.

Ссылки

  1. Экспортируемость компонентов
  2. Основы ContentProvider
К началу