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

Небезопасный protectionLevel у разрешения

Описание

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

Разрешения защищают доступ к:

  • данным с ограниченным правом на использование, таким как состояние системы и контактная информация пользователей;

  • запрещенным действиям, среди которых — подключение к сопряженному устройству и запись звука.

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

Общие положения Android-разрешений

Существует несколько типов разрешений:

Install-time permissions — предоставляются автоматически при установке приложения. Разрешения во время загрузки дают приложению неполный доступ к данным или позволяют ему выполнять ограниченные действия, которые минимально влияют на систему или другие программные продукты. Android включает несколько install-time permissions: normal permissions и signature permissions, которые отличаются уровнем защиты (normal и signature).

Runtime permissions (dangerous permissions) — требуют, чтобы приложение запросило разрешение во время выполнения. Предоставляет продукту дополнительный доступ к данным с ограниченными правами или разрешает ему выполнять некоторые действия, которые существенно влияют на систему и другие приложения. Этим permissions система присваивает dangerous уровень защиты.

Special permissions — соответствуют конкретным операциям приложения. Только Android-платформа и OEM (оригинальный производитель оборудования) могут определять специальные разрешения в тех случаях, когда хотят защитить доступ к особенно мощным действиям, таким как отрисовка поверх других приложений. Этим разрешениям система присваивает appop уровень защиты. В отличие от runtime permissions, здесь пользователь должен предоставить специальные разрешения на странице «Доступ к специальному приложению» в системных настройках. Приложения могут отправлять туда пользователей с помощью Intent, который приостанавливает ПО и запускает соответствующую страницу настроек для данного специального разрешения. После того, как пользователь вернется в приложение, оно может проверить, предоставлено ли разрешение в функции onResume().

Группы разрешений

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

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

<permission-group android:name="android.permission-group.MESSAGES"
    android:label="@string/permgrouplab_messages"
    android:icon="@drawable/perm_group_messages"
    android:description="@string/permgroupdesc_messages"
    android:permissionGroupFlags="personalInfo"
    android:priority="360"/>

<!-- Allows an application to monitor incoming SMS messages, to record or perform processing on them. -->
<permission android:name="android.permission.RECEIVE_SMS"
    android:permissionGroup="android.permission-group.MESSAGES"
    android:protectionLevel="dangerous"
    android:label="@string/permlab_receiveSms"
    android:description="@string/permdesc_receiveSms" />

<!-- Allows an application to send SMS messages. -->
<permission android:name="android.permission.SEND_SMS"
    android:permissionGroup="android.permission-group.MESSAGES"
    android:protectionLevel="dangerous"
    android:permissionFlags="costsMoney"
    android:label="@string/permlab_sendSms"
    android:description="@string/permdesc_sendSms" />

Разрешения используются, чтобы понять, имеет ли приложение права доступа к чувствительным данным или право на выполнение определенных операций (действий). Например, если программный продукт хочет получить доступ к контактам, то разработчику необходимо объявить разрешение в файле AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_CONTACTS" />

Это встроенное разрешение, которое имеет уровень защиты (protectionLevel) — dangerous. При установке приложения с данным разрешением Android ОС спросит пользователя, хочет ли он предоставить доступ к данным своих контактов.

Разработчики могут создать свои разрешения. Для этого их нужно прописать в файле AndroidManifest.xml:

<permission android:name="com.mycoolcam.USE_COOL_CAMERA"
    android:protectionLevel="dangerous" />

<activity android:name=".CoolCamActivity" android:exported="true" android:permission="com.mycoolcam.USE_COOL_CAMERA">
<intent-filter>
    <action android:name="com.mycoolcam.LAUNCH_COOL_CAM" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Если какое-то стороннее приложение захочет использовать данные Activity, то разрешения необходимо также прописать в файле AndroidManifest.xml этого продукта:

<uses-permission android:name="com.mycoolcam.USE_COOL_CAMERA" />

И тогда при установке приложения ОС Android спросит пользователя, давать ли доступ приложению к камере или нет.

Уровни разрешений

  1. normal — пользователь не знает, что приложение запрашивает доступ к этому ресурсу, потому что права предоставляются автоматически при установке;

  2. dangerous — этот уровень требует, чтобы пользователь подтвердил, может ли приложение получить доступ к определенному ресурсу;

  3. signature — приложение, использующее этот уровень разрешений, должно быть подписано тем же сертификатом, что и продукт, объявивший его. Это не позволяет злоумышленнику прописать <uses-permission> с этим разрешением в файле AndroidManifest.xml, потому что Android не даст установить приложение;

  4. Есть несколько других уровней, таких как system, installer, privileged, appop и т. д., которые используются системными приложениями. Их следует рассматривать как уровень signature с точки зрения злоумышленника, т. е. разрешения, использующие этот уровень защиты, не могут быть объявлены в <uses-permission>.

Некоторые разрешения, такие как CAMERA, позволяют вашему приложению получать доступ к аппаратным частям, которые есть только у некоторых устройств Android. Если ваше приложение объявляет одно из этих hardware-associated permissions, подумайте, сможет ли оно работать на устройстве, не имеющем этого оборудования. В большинстве случаев оборудование является необязательным, поэтому лучше и назвать его таковым, задав для android:required значение false в объявлении <uses-feature>, как показано в следующем фрагменте кода из файла AndroidManifest.xml:

<uses-feature android:name="android.hardware.camera"
    android:required="false" />

Если вы не установите для android:required значение false в объявлении <uses-feature>, Android предположит, что для запуска вашего приложения требуется аппаратное обеспечение. Система запретит некоторым устройствам устанавливать ваше приложение.

Атрибут android:protectionLevel у разрешения характеризует потенциальный риск, подразумеваемый в разрешении, и указывает процедуру, которой должна следовать система при определении того, следует ли предоставлять разрешение запрашивающему его приложению.

<permission
    android:name="com.test.MyPermission"
    android:protectionLevel="normal" />

Существует несколько уровней protectionLevel:

Уровень Описание
normal Значение по умолчанию. Разрешение с низким уровнем риска, которое предоставляет запрашивающим приложениям доступ к изолированным функциям уровня приложения с минимальным риском для других приложений, системы или пользователя. Система автоматически предоставляет этот тип разрешения запрашивающему приложению при установке, не запрашивая явного согласия пользователя, хотя у него всегда есть возможность просмотреть эти разрешения перед установкой
dangerous Разрешение повышенного риска, которое предоставляет запрашивающему приложению доступ к личным данным пользователя или контроль над устройством, что может негативно повлиять на пользователя. Поскольку этот тип разрешения представляет потенциальный риск, система может не предоставить его автоматически запрашивающему приложению. Например, любые опасные разрешения, запрошенные приложением, могут отображаться пользователю и требовать подтверждения перед продолжением, или может быть использован какой-либо другой подход, чтобы избежать автоматического разрешения пользователем использования таких возможностей
signature Разрешение, которое система предоставляет только в том случае, если запрашивающее приложение подписано тем же сертификатом, что и приложение, объявившее разрешение. Если сертификаты совпадают, система автоматически предоставляет разрешение, не уведомляя пользователя и не запрашивая его явного согласия
knownSigner Разрешение, которое система предоставляет только в том случае, если запрашивающее приложение подписано разрешенным сертификатом. Если сертификат запрашивающей стороны указан в списке, система автоматически предоставляет разрешение, не уведомляя пользователя и не запрашивая его явного согласия
signatureOrSystem Разрешение, которое система предоставляет только приложениям, которые находятся в выделенной папке образа системы Android или подписаны тем же сертификатом, что и приложение, объявившее разрешение. Избегайте использования этой опции, поскольку уровень защиты «подпись» достаточен для большинства нужд и работает независимо от того, где установлены приложения.
Разрешение signatureOrSystem используется в определенных особых ситуациях, когда приложения нескольких поставщиков встроены в образ системы и им необходимо явно использовать определенные функции, поскольку они создаются вместе

Проблема

  1. Если не указать у разрешения атрибут android:protectionLevel, то по умолчанию оно будет уровня normal и его можно спокойно использовать без уведомления пользователя. То есть можно по ошибке дать доступ к чувствительным данным пользователя. Аналогичную ошибку допустили разработчики встроенного приложения Samsung, что привело к тому, что другие приложения на телефоне могли читать историю звонков, SMS-сообщения и т. д.

  2. В случае «экосистемы» приложений, если использованное разрешение не объявлено в каждом из приложений, то при установке только одного из них, разрешение будет иметь android:protectionLevel уровня normal, что позволит любому стороннему приложению получить к доступ к данным пользователя.

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

При объявлении «своих» (кастомных) разрешений необходимо не забывать о android:protectionLevel. Также необходимо убедиться в наличии атрибута android:protectionLevel со значением dangerous, signatureOrSystem или signature.

Плохо Хорошо
<permission
android:name="com.test.MyPermission"
android:protectionLevel="normal" />
<permission
android:name="com.test.MyPermission"
android:protectionLevel="dangerous,signatureOrSystem или signature" />

Предположим, экосистема состоит из двух продуктов: My Cool Cam и My Cool Reader. Первый для чтения использует функциональные возможности второго.

Манифест приложения-камеры:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mycoolcam">
    <permission android:name="com.mycoolcam.USE_COOL_CAMERA" android:protectionLevel="signature" />
    <uses-permission android:name="com.mycoolcam.USE_COOL_CAMERA" />

    <application android:label="My Cool Cam">
        <activity android:name=".CoolCamActivity" android:exported="true" android:permission="com.mycoolcam.USE_COOL_CAMERA">
            <intent-filter>
                <action android:name="com.mycoolcam.LAUNCH_COOL_CAM" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <!-- ... -->
    </application>
</manifest>

Манифест приложения для чтения:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mycoolreader">
    <uses-permission android:name="com.mycoolcam.USE_COOL_CAMERA" />

    <application android:label="My Cool Reader">
        <provider android:name=".AllUserNotesContentProvider" android:authorities="com.mycoolreader.notes_provider" android:exported="true" android:permission="com.mycoolcam.USE_COOL_CAMERA" />
        <!-- ... -->
    </application>
</manifest>

На первый взгляд может показаться, что всё хорошо и безопасно, поскольку только приложения из экосистемы могут получить доступ к конфиденциальной информации, хранящейся в AllUserNotesContentProvider. Но если на устройстве жертвы установлено только приложение для чтения, в этом случае система Android ничего не будет знать об объявлении разрешений com.mycoolcam.USE_COOL_CAMERA, и поэтому уровень по умолчанию будет помечен как обычный.

Чтобы предотвратить это, убедитесь, что каждое разрешение из экосистемы нескольких приложений объявляется индивидуально во всех продуктах.

Плохо Хорошо
Разрешение из экосистемы нескольких приложений объявляется только в одном приложении экосистемы Разрешение из экосистемы нескольких приложений объявляется индивидуально во всех продуктах

Ссылки

  1. Permissions on Android.
  2. Распространенные ошибки при использовании разрешений в Android.
  3. Permissions в Android: как не допустить ошибок при разработке.
К началу