Как определить специальное разрешение для приложения

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

Фон

Android – это операционная система с разделением привилегий, в которой каждое приложение выполняется с уникальным системным идентификатором (идентификатором пользователя и группы Linux). Части системы также разделены на отдельные идентификаторы. Таким образом, Linux изолирует приложения друг от друга и от системы.

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

Подписи приложений

Все APK-файлы должны быть подписаны сертификатом, закрытый ключ которого хранится у разработчика. Сертификат не должен быть подписан центром сертификации. В приложениях для Android разрешено и принято использовать самозаверяющие сертификаты. Сертификаты в Android используются для идентификации авторов приложений. Это позволяет системе предоставлять приложениям разрешения на уровне подписи или отказывать в них, а также одобрять или отклонять запросы приложений на получение того же идентификатора Linux, что и у другого приложения.

Предоставление разрешений на подпись после изготовления устройства

Начиная с Android 12 (уровень API 31) атрибут knownCerts для разрешений на уровне подписи позволяет ссылаться на дайджесты известных сертификатов подписи во время объявления.

Вы можете объявить атрибут knownCerts и использовать флаг knownSigner в атрибуте protectionLevel приложения для определенного разрешения на уровне подписи. Затем система предоставляет это разрешение запрашивающему приложению, если любой подписант в цепочке подписей запрашивающего приложения, включая текущего подписанта, соответствует одному из дайджестов, объявленных с разрешением в атрибуте knownCerts.

Флаг knownSigner позволяет устройствам и приложениям предоставлять разрешения на подпись другим приложениям без необходимости подписывать приложения во время производства и поставки устройств.

Идентификаторы пользователей и доступ к файлам

При установке Android присваивает каждому пакету уникальный идентификатор пользователя Linux. Идентификатор остается неизменным в течение всего времени, пока пакет находится на устройстве. На другом устройстве у того же пакета может быть другой UID. Важно, чтобы на одном устройстве у каждого пакета был уникальный UID.

Поскольку безопасность обеспечивается на уровне процессов, код двух пакетов обычно не может выполняться в одном процессе, так как они должны запускаться от имени разных пользователей Linux.

Любые данные, хранящиеся в приложении, назначаются идентификатору пользователя этого приложения и обычно недоступны для других пакетов.

Дополнительную информацию о модели безопасности Android можно найти в обзоре безопасности Android.

Определение и применение разрешений

Чтобы применить собственные разрешения, сначала объявите их в файле AndroidManifest.xml с помощью одного или нескольких элементов <permission>.

Правила именования

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

Рекомендуем добавлять в начало названия разрешения название пакета приложения, используя стиль обратного домена, а затем .permission. и описание возможности, которую предоставляет разрешение, в верхнем змеином регистре. Пример: com.example.myapp.permission.ENGAGE_HYPERSPACE.

Это позволит избежать конфликтов имен и поможет четко определить владельца и назначение специального разрешения.

Пример

Например, приложение, которому необходимо контролировать, какие другие приложения могут запускать одно из его действий, может объявить разрешение для этой операции следующим образом:

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >
    
    <permission
      android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
      android:label="@string/permlab_deadlyActivity"
      android:description="@string/permdesc_deadlyActivity"
      android:permissionGroup="android.permission-group.COST_MONEY"
      android:protectionLevel="dangerous" />
    ...
</manifest>

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

Атрибут android:permissionGroup является необязательным и используется только для того, чтобы система могла показать пользователю разрешения. В большинстве случаев в качестве значения этого параметра указывается стандартная системная группа (перечислены в android.Manifest.permission_group), хотя вы можете определить группу самостоятельно, как описано в следующем разделе. Рекомендуем использовать существующую группу, чтобы упростить интерфейс разрешений, который видит пользователь.

Для разрешения необходимо указать как ярлык, так и описание. Это строковые ресурсы, которые пользователь видит при просмотре списка разрешений (android:label) или сведений об отдельном разрешении (android:description). Ярлык – это краткое описание (несколько слов) основной функции, которую защищает разрешение. Описание состоит из двух предложений. В первом рассказывается, что позволяет делать разрешение, а во втором – о возможных последствиях, если разрешение будет предоставлено приложению.

Ниже приведен пример ярлыка и описания для разрешения CALL_PHONE.

<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the app to call non-emergency
phone numbers without your intervention. Malicious apps may cause unexpected
calls on your phone bill.</string>

Как создать группу разрешений

Как показано в предыдущем разделе, вы можете использовать атрибут android:permissionGroup, чтобы помочь системе описать разрешения пользователю. В большинстве случаев для этого используется стандартная системная группа (перечислены в android.Manifest.permission_group), но вы также можете определить собственную группу с помощью <permission-group>.

Элемент <permission-group> определяет ярлык для набора разрешений, как объявленных в манифесте с помощью элементов <permission>, так и объявленных в других местах. Это влияет только на то, как разрешения группируются при показе пользователю. Элемент <permission-group> не указывает разрешения, которые принадлежат группе, но дает ей название.

Чтобы добавить разрешение в группу, присвойте ее название атрибуту permissionGroup элемента <permission>.

Элемент <permission-tree> объявляет пространство имен для группы разрешений, определенных в коде.

Рекомендации по специальным разрешениям

Вы можете задать специальные разрешения для своих приложений и запрашивать их у других приложений, используя элементы <uses-permission>. Однако тщательно оцените, необходимо ли это делать.

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

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

Дополнительная информация:

<uses-permission>
Документация по API для тега манифеста, который объявляет системные разрешения, необходимые для работы приложения.

Вас также может заинтересовать:

Общие сведения о безопасности Android
Подробное описание модели безопасности платформы Android.