Управление доступом на основе разрешений к экспортированным компонентам

Категория OWASP: MASVS-PLATFORM: Взаимодействие платформ

Обзор

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

Уровни разрешений Android указывают на потенциальный риск, связанный с данным разрешением:

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

Уязвимости, связанные с управлением доступом на основе разрешений, возникают, когда компонент приложения (например, активность , приемник , поставщик контента или служба ) соответствует всем следующим критериям:

  • Данный компонент не связан ни с одним android:permission в Manifest ;
  • Данный компонент выполняет конфиденциальную задачу, для которой существуют разрешения, уже одобренные пользователем;
  • Компонент экспортируется;
  • Данный компонент не выполняет никаких проверок разрешений вручную (ни на уровне манифеста, ни на уровне кода);

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

Влияние

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

Меры по смягчению последствий

Для выполнения конфиденциальных задач требуются разрешения.

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

Разработчики могут запрашивать разрешения для входящих запросов либо путем объявления их в файле Manifest , либо на уровне кода при реализации сервиса, как показано в следующих примерах.

XML

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

    <application ...>
        <service android:name=".MyExportService"
                 android:exported="true"
                 android:permission="android.permission.READ_CONTACTS" />

        </application>
</manifest>

Котлин

class MyExportService : Service() {

    private val binder = MyExportBinder()

    override fun onBind(intent: Intent): IBinder? {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
        // Permission is enforced, proceed with export logic
        return binder
    }

    // Inner class for your Binder implementation
    private inner class MyExportBinder : Binder() {
        // Permission is enforced, proceed with export logic
    }
}

Java

public class MyExportService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");

        return binder;

    }

    // Inner class for your Binder implementation
    private class MyExportBinder extends Binder {
        // Permission is enforced, proceed with export logic

    }
}

Не экспортируйте компонент.

Избегайте экспорта компонентов, имеющих доступ к конфиденциальным ресурсам, если это не является абсолютно необходимым. Этого можно добиться, установив для параметра android:exported в файле Manifest значение false для вашего компонента. Начиная с API уровня 31 и выше, этот атрибут по умолчанию имеет значение false .

XML

<activity
    android:name=".MyActivity"
    android:exported="false"/>

Примените разрешения на основе подписи.

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

XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

Конечные точки для выполнения одной задачи

При разработке приложения следуйте принципу разделения ответственности (Separation of Concerns) . Каждая конечная точка должна выполнять лишь небольшой набор конкретных задач с определенными правами доступа. Этот хороший подход к проектированию также позволяет разработчику применять детальные разрешения для каждой конечной точки. Например, избегайте создания одной конечной точки, которая обслуживает как календарь, так и контакты.

Ресурсы