Категория 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
При задании пользовательских разрешений используйте проверку кода Android (lint checks), чтобы находить опечатки и другие потенциальные ошибки в коде.
Соглашение об именовании
Используйте единообразную систему именования, чтобы опечатки были более заметны. Тщательно проверяйте объявления пользовательских разрешений в манифесте вашего приложения на наличие опечаток.
Риск: Лишенные прав доступа
Разрешения используются для защиты ресурсов приложений. Приложение может объявить о необходимых разрешениях для доступа к ресурсам в двух разных местах:
- AndroidManifest.xml: Предопределено в файле AndroidManifest.xml (если не указано, используются разрешения
<application>), например, разрешение поставщика , разрешение получателя , разрешение активности , разрешение службы ; - Код: Регистрируется в коде среды выполнения, например,
registerReceiver().
Однако иногда эти разрешения не определены соответствующим тегом <permission> в манифесте APK-файла на устройстве. В этом случае они называются "осиротевшими разрешениями" . Такая ситуация может возникнуть по ряду причин, например:
- Возможно, произойдёт рассинхронизация между обновлениями в манифесте и кодом проверки прав доступа.
- APK-файл с необходимыми разрешениями может не быть включен в сборку, или может быть включена неправильная версия.
- В поле «Имя разрешения» как в проверке, так и в манифесте может быть указано с ошибкой.
Вредоносное приложение может определить «осиротевшее» разрешение и получить к нему доступ. В этом случае привилегированные приложения, которые доверяют этому «осиротевшему» разрешению для защиты компонента, могут быть скомпрометированы.
В случаях, когда привилегированное приложение использует разрешение для защиты или ограничения какого-либо компонента, это может предоставить вредоносному приложению доступ к этому компоненту. Примерами могут служить запуск действий, защищенных разрешением, доступ к поставщику контента или трансляция на приемник широковещательных сообщений, защищенный неиспользуемым разрешением.
Это также может создать ситуацию, когда привилегированное приложение будет обмануто и поверит, что вредоносное приложение является легитимным, и, следовательно, начнет загружать файлы или контент.
Меры по смягчению последствий
Убедитесь, что все пользовательские разрешения, которые ваше приложение использует для защиты компонентов, также определены в вашем Manifest-файле.
Приложение использует пользовательские разрешения 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
Этот атрибут описывает потенциальный уровень риска, связанный с разрешением, и указывает, какие процедуры должна выполнить система при принятии решения о предоставлении или отказе в предоставлении разрешения.
Меры по смягчению последствий
Избегайте обычного или опасного уровня защиты.
Использование обычного или опасного protectionLevel для ваших разрешений означает, что большинство приложений могут запрашивать и получать необходимые разрешения:
- Для того чтобы считаться "нормальным", достаточно лишь объявить об этом.
- «Опасный» будет одобрен многими пользователями.
Следовательно, эти protectionLevels обеспечивают незначительную безопасность.
Использовать разрешения для подписи (Android >= 10)
По возможности используйте уровни защиты подписью. Это гарантирует, что доступ к защищенным функциям смогут получить только другие приложения, подписанные тем же сертификатом, что и приложение, создавшее разрешение. Убедитесь, что вы используете выделенный (не повторно используемый) сертификат подписи и надежно храните его в хранилище ключей .
В файле Manifest укажите пользовательское разрешение следующим образом:
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 и должно будет объявить об этом в своем Manifest следующим образом:
XML
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
Остерегайтесь пользовательских разрешений для подписи (Android < 10)
Если ваше приложение ориентировано на Android < 10, то при удалении или обновлении приложения и удалении пользовательских разрешений могут существовать вредоносные приложения, способные продолжать использовать эти разрешения и, таким образом, обходить проверки. Это связано с уязвимостью повышения привилегий ( CVE-2019-2200 ), которая была исправлена в Android 10.
Это одна из причин (наряду с риском возникновения состояний гонки), почему рекомендуется использовать проверку подписи вместо пользовательских разрешений.
Риск: Состояние гонки
Если легитимное приложение A определяет пользовательское разрешение на подпись, используемое другими приложениями X , но впоследствии удаляется, то вредоносное приложение B может определить то же самое пользовательское разрешение с другим protectionLevel , например, обычным . Таким образом, B получает доступ ко всем компонентам, защищенным этим пользовательским разрешением в приложениях X без необходимости подписываться тем же сертификатом, что и приложение A
То же самое произойдет, если B будет установлен раньше A
Меры по смягчению последствий
Если вы хотите, чтобы компонент был доступен только приложениям, подписанным тем же сертификатом, что и предоставляющее приложение, вы можете обойтись без определения пользовательских разрешений для ограничения доступа к этому компоненту. В этом случае можно использовать проверку подписи. Когда одно из ваших приложений отправляет запрос другому приложению, второе приложение может проверить, что оба приложения подписаны одним и тем же сертификатом, прежде чем выполнить запрос.
Ресурсы
- Сведите к минимуму количество запросов на получение разрешений.
- Обзор разрешений
- Описание уровней защиты
- CustomPermissionTypo Android Lint
- Как использовать Android Lint
- Научная статья с подробным объяснением разрешений Android и интересными результатами фаззинг-тестирования.