Категория 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) . Каждая конечная точка должна выполнять лишь небольшой набор конкретных задач с определенными правами доступа. Этот хороший подход к проектированию также позволяет разработчику применять детальные разрешения для каждой конечной точки. Например, избегайте создания одной конечной точки, которая обслуживает как календарь, так и контакты.
Ресурсы
- Доступ к защищенным компонентам приложений для Android из блога Oversecured.
- Рекомендации для поставщиков контента
- Разрешения во время выполнения (опасные)
- Принцип разделения ответственности
- Документация по разрешениям Android
- Советы по безопасности приемников трансляции Android
- Советы по безопасности служб Android
- В Android 12 (API 31) значение по умолчанию для экспортируемых данных установлено на "false".
- Проверка синтаксиса: Экспортируемый объект PreferenceActivity не следует экспортировать.
- Проверка синтаксиса: Экспортированному получателю не требуются разрешения.
- Проверка синтаксиса: для работы экспортируемой службы не требуются разрешения.