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

Небезопасный доступ к Content Provider

Описание

Что такое Content Provider?

Как следует из названия, Content Provider, отвечает за предоставление данных и управление доступом к ним. Эти данные могут храниться в файловой системе, в базе данных SQLite или в любом другом постоянном хранилище, доступном из вашего приложения. С помощью Content Provider любое приложение с соответствующими разрешениями может читать или даже изменять данные, используя стандартный набор API, который позволяет выполнять необходимые транзакции.

Для защиты данных Content Provider имеет ряд атрибутов, см. ниже.

Атрибут Описание
android:permission Указывается разрешение, которое требуется для доступа к данным Content Provider
android:readPermission Указывается разрешение, которое требуется для чтения данных Content Provider
android:writePermission Указывается разрешение, которое требуется для записи данных Content Provider
<grant-uri-permission
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
/>
Указывает подмножества данных приложения, к которым у Content Provider есть разрешение на доступ
<path-permission
android:path="string"
android:pathPrefix="string"
android:pathPattern="string"
android:permission="string"
android:readPermission="string"
android:writePermission="string"
/>
Определяет путь и необходимые разрешения для определенного подмножества данных внутри Content Provider. Этот элемент можно указать несколько раз, чтобы указать несколько путей

Данные атрибуты рекомендуется использовать для защиты чувствительных данных пользователя.

Проблема

При отсутствии атрибутов, описанных выше, существует риск получить свободный доступ к данным пользователя через Content Provider (сторонним приложениям).

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

Необходимо ограничивать доступ к Content Provider с помощью атрибутов android:permission, android:readPermission или android:writePermission, или предоставлять доступ только к конкретным uri с помощью <grant-uri-permission …/>, либо <path-permission.…. А также, если у Content Provider есть атрибуты android:readPermission и android:writePermission одновременно, то не рекомендуется использовать одно и то же разрешение, чтобы, например, приложения, которым необходимо только чтение, не получали дополнительную возможность на запись и наоборот.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.test.appwithpermission">

    <!-- Провайдер имеет одинаковые разрешения на чтение и запись — это плохо -->
    <provider android:name=".MyProvider"
        android:authorities="contacts;com.android.contacts"
        android:readPermission="android.permission.READ_CONTACTS"
        android:writePermission="android.permission.READ_CONTACTS"
        android:exported="true"/>

    <!-- Провайдер имеет разные разрешения на чтение и запись — это хорошо -->
    <provider android:name=".MyProvider"
        android:authorities="contacts;com.android.contacts"
        android:readPermission="android.permission.READ_CONTACTS"
        android:writePermission="android.permission.WRITE_CONTACTS"
        android:exported="true"/>

</manifest>
Плохо Хорошо
Content Provider не защищён атрибутами android:permission, android:readPermission или android:writePermission, а также доступ не ограничен конкретными uri.
Или Content Provider использует одно и то же разрешение для атрибутов android:readPermission и android:writePermission
Content Provider защищён атрибутами android:permission, android:readPermission или android:writePermission, а также доступ ограничен конкретными uri с помощью <grant-uri-permission …/>, либо <path-permission.….
И/или Content Provider использует разные разрешения для атрибутов android:readPermission и android:writePermission.

Ссылки

  1. Permissions on Android
  2. Распространенные ошибки при использовании разрешений в Android
  3. Permissions в Android: как не допустить ошибок при разработке
  4. Content Provider шарит все свои данные
  5. Описание флагов для открытия доступа к определенному Uri
К началу