Категория OWASP: MASVS-CODE: качество кода
Обзор
Риски, связанные со специальными разрешениями, возникают, когда определение специального разрешения отсутствует или написано с ошибкой, или когда соответствующий атрибут android:protectionLevel неправильно используется в манифесте.
Например, злоумышленники могут создать специальное разрешение с тем же названием, но определенное вредоносным приложением и с другими уровнями защиты.
Специальные разрешения предназначены для того, чтобы делиться ресурсами и возможностями с другими приложениями. Примеры допустимого использования специальных разрешений:
- Управление межпроцессным взаимодействием (IPC) между двумя или более приложениями.
- Доступ к сторонним сервисам
- Ограничение доступа к общим данным приложения
Влияние
Вредоносное приложение может получить доступ к защищенным ресурсам. Последствия уязвимости зависят от защищаемого ресурса и разрешений, связанных с исходным сервисом приложения.
Риск: опечатки в специальных разрешениях
В манифесте может быть объявлено специальное разрешение, но для защиты экспортированных компонентов Android используется другое специальное разрешение из-за опечатки. Вредоносное приложение может использовать приложения с неправильно написанным разрешением, чтобы:
- Сначала зарегистрируйте это разрешение.
- Прогнозирование написания в последующих приложениях
Это может позволить приложению получить несанкционированный доступ к ресурсам или контроль над приложением жертвы.
Например, уязвимое приложение хочет защитить компонент с помощью разрешения READ_CONTACTS, но случайно указывает разрешение READ_CONACTS. Вредоносное приложение может заявить права на READ_CONACTS, поскольку оно не принадлежит ни одному приложению (или системе), и получить доступ к защищенному компоненту. Другой распространенный вариант этой уязвимости – android:permission=True. Значения true и false, независимо от регистра, являются недопустимыми для декларации разрешений и обрабатываются так же, как и другие опечатки в декларации специальных разрешений. Чтобы устранить эту проблему, измените значение атрибута android:permission на допустимую строку разрешения. Например, если приложению нужен доступ к контактам пользователя, атрибут android:permission должен иметь значение android.permission.READ_CONTACTS.
Предотвращение атак
Проверки Android Lint
При объявлении специальных разрешений используйте проверки Android Lint, чтобы находить опечатки и другие потенциальные ошибки в коде.
Правила именования
Используйте единые правила именования, чтобы опечатки были заметнее. Внимательно проверьте декларации разрешений в манифесте приложения на наличие опечаток.
Риск: разрешения без владельца
Разрешения используются для защиты ресурсов приложений. Разрешения, необходимые для доступа к ресурсам, можно объявить в двух местах:
- AndroidManifest.xml.Заранее определены в файле AndroidManifest.xml (если не указаны, используются разрешения
<application>), например provider permission, receiver permission, activity permission, service permission. - Код. Регистрируется в коде среды выполнения, например
registerReceiver().
Однако иногда эти разрешения не определяются соответствующим тегом <permission> в манифесте APK на устройстве. В этом случае они называются осиротевшими разрешениями. Это может произойти по нескольким причинам, например:
- Обновления манифеста и кода с проверкой разрешений могут быть не синхронизированы.
- APK-файл с разрешениями не включен в сборку или включена неверная версия.
- Название разрешения в проверке или манифесте может быть написано неправильно.
Вредоносное приложение может определить разрешение, не связанное с приложением, и получить его. В этом случае приложения с привилегиями, которые доверяют потерянному разрешению для защиты компонента, могут быть скомпрометированы.
Если привилегированное приложение использует разрешение для защиты или ограничения какого-либо компонента, вредоносное приложение может получить доступ к этому компоненту. Например, запуск действий, защищенных разрешением, доступ к поставщику контента или передача данных широковещательному приемнику, защищенному потерянным разрешением.
Кроме того, вредоносное приложение может выдать себя за легитимное и загрузить файлы или контент.
Предотвращение атак
Убедитесь, что все специальные разрешения, которые ваше приложение использует для защиты компонентов, также определены в манифесте.
Приложение использует специальные разрешения my.app.provider.READ и my.app.provider.WRITE, чтобы защитить доступ к поставщику контента.
XML
<provider android:name="my.app.database.CommonContentProvider" android:readPermission="my.app.provider.READ" android:writePermission="my.app.provider.WRITE" android:exported="true" android:process=":myappservice" android:authorities="my.app.database.contentprovider"/>
Приложение также определяет и использует следующие специальные разрешения, чтобы не позволить вредоносным приложениям сделать то же самое:
XML
<permission android:name="my.app.provider.READ"/>
<permission android:name="my.app.provider.WRITE"/>
<uses-permission android:name="my.app.provider.READ" />
<uses-permission android:name="my.app.provider.WRITE" />
Риск: неправильное использование android:protectionLevel
Этот атрибут описывает потенциальный уровень риска в разрешении и указывает, каким процедурам должна следовать система при принятии решения о предоставлении разрешения.
Предотвращение атак
Избегайте нормального или опасного уровня защиты
Если для разрешений задан уровень normal или dangerous protectionLevel, то большинство приложений могут запрашивать и получать их.
- "normal" – достаточно объявить разрешение;
- "опасный" будет одобрен многими пользователями
Поэтому такие protectionLevels не обеспечивают достаточную безопасность.
Использовать разрешения для подписи (Android 10 и более поздних версий)
По возможности используйте уровни защиты подписи. Это гарантирует, что доступ к защищенным функциям получат только приложения, подписанные тем же сертификатом, что и приложение, создавшее разрешение. Убедитесь, что вы используете выделенный (не повторно используемый) сертификат подписи, и надежно храните его в хранилище ключей.
Определите специальное разрешение в манифесте следующим образом:
XML
<permission
android:name="my.custom.permission.MY_PERMISSION"
android:protectionLevel="signature"/>
Ограничьте доступ, например к действию, только теми приложениями, которым предоставлено это специальное разрешение, следующим образом:
XML
<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>
Любое другое приложение, подписанное тем же сертификатом, что и приложение, объявившее это специальное разрешение, получит доступ к действию .MyActivity. В его манифесте должно быть указано следующее:
XML
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
Остерегайтесь специальных разрешений для подписи (Android < 10)
Если ваше приложение предназначено для Android 9 или более ранней версии, то при удалении специальных разрешений из-за удаления или обновления приложения вредоносные приложения могут по-прежнему использовать эти разрешения и обходить проверки. Это связано с уязвимостью, позволяющей повысить уровень прав доступа (CVE-2019-2200), которая была устранена в Android 10.
Это одна из причин (наряду с риском состояния гонки), по которой рекомендуется использовать проверку подписи, а не специальные разрешения.
Риск: состояние гонки
Если легальное приложение A определяет специальное разрешение на подпись, которое используется другими приложениями X, но затем удаляется, то вредоносное приложение B может определить то же специальное разрешение с другим protectionLevel, например normal. Таким образом, B получает доступ ко всем компонентам, защищенным этим специальным разрешением в приложениях X, без необходимости подписывать его тем же сертификатом, что и приложение A.
То же самое произойдет, если B будет установлено до A.
Предотвращение атак
Если вы хотите, чтобы компонент был доступен только приложениям, подписанным той же подписью, что и предоставляющее его приложение, вы можете не определять специальные разрешения для ограничения доступа к этому компоненту. В этой ситуации вы можете использовать проверки подписи. Когда одно из ваших приложений отправляет запрос другому, второе приложение может проверить, подписаны ли они одним и тем же сертификатом, прежде чем выполнить запрос.
Ресурсы
- Минимизируйте запросы разрешений
- Обзор разрешений
- Описание уровней защиты
- CustomPermissionTypo Android Lint
- Как использовать Android Lint
- Научная статья с подробным объяснением разрешений Android и интересными результатами фаззинг-тестирования