Permission Broker: гранулярный доступ мини-программ в Super App

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Permission Broker: гранулярный доступ мини-программ в Super App
Сложный
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    744
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1161
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    968
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    563

Гранулярное управление доступом мини-программ в Super App

При разработке Super App мы столкнулись с задачей разграничения доступа мини-программ к ресурсам хоста. Каждая мини-программа не должна иметь прямой доступ к камере или геолокации — иначе пользователь потеряет контроль над своими данными. Представьте: мини-программа доставки запрашивает геолокацию каждые 10 секунд в фоне. Без гранулярного контроля пользователь не сможет это отключить. Мы решили эту проблему через permission broker — центральный компонент, который проверяет каждое обращение к чувствительному API. Наш опыт показывает, что ключевое решение — гранулярная система разрешений с двумя независимыми слоями. Permission broker снижает риски утечек в 3 раза по сравнению с монолитным управлением.

Как устроена система разрешений?

Система разрешений для мини-программ — это не просто обёртка над системными ActivityCompat.requestPermissions. Здесь два независимых слоя:

  • Первый слой: платформенные разрешения — camera, location, contacts, которые запрашивает любое Android/iOS приложение. Хост-приложение держит их у себя и делегирует мини-программе только то, что явно разрешено.
  • Второй слой: платформенные API-разрешения — доступ к API самого Super App: хранилище профиля пользователя, история заказов, платёжные методы, контакты внутри экосистемы. Это полностью кастомный слой, системные разрешения здесь не помогают.
Слой Примеры Управление
Системный LOCATION, CAMERA, CONTACTS Через системный диалог, делегируется хостом
Платформенный USER_PROFILE_READ, PAYMENT_INITIATE Кастомный диалог, permission broker

Состояния разрешений в permission store:

Статус Описание Действие broker
GRANTED Разрешено Пропустить вызов
DENIED Отказано Вернуть ошибку
DENIED_PERMANENTLY Отказано навсегда Не показывать диалог

Что такое манифест мини-программы?

Каждая мини-программа поставляется с манифестом, где декларирует нужные permissions:

{
  "miniappId": "com.partner.food_delivery",
  "version": "1.2.0",
  "permissions": {
    "system": ["LOCATION_FINE", "CAMERA"],
    "platform": ["USER_PROFILE_READ", "PAYMENT_INITIATE", "ORDER_HISTORY_READ"]
  },
  "permissionRationale": {
    "LOCATION_FINE": "Для расчёта адреса доставки",
    "CAMERA": "Для сканирования QR-кодов меню"
  }
}

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

Как работает Permission Broker?

Центральный компонент — broker, который проверяет все обращения к нативным API. Мы реализовали его на Kotlin с использованием корутин. Алгоритм работы:

  1. Проверка манифеста: разрешение должно быть задекларировано.
  2. Проверка permission store: если уже сохранён статус GRANTED или DENIED_PERMANENTLY, возвращается соответствующее решение.
  3. Для системных разрешений: проверяем, имеет ли хост нужное разрешение. Если нет — запрашиваем у пользователя через системный диалог.
  4. Для платформенных: показываем кастомный диалог с описанием.
  5. Сохраняем решение пользователя в permanent store.
class MiniAppPermissionBroker(
    private val permissionStore: MiniAppPermissionStore,
    private val systemPermissionDelegate: SystemPermissionDelegate
) {

    suspend fun requestPermission(
        miniAppId: String,
        permission: MiniAppPermission,
        context: Activity
    ): PermissionResult {

        // 1. Задекларирована ли в манифесте?
        if (!manifestValidator.isDeclared(miniAppId, permission)) {
            return PermissionResult.DENIED_NOT_DECLARED
        }

        // 2. Уже выдана?
        val stored = permissionStore.getStatus(miniAppId, permission)
        if (stored == PermissionStatus.GRANTED) return PermissionResult.GRANTED
        if (stored == PermissionStatus.DENIED_PERMANENTLY) return PermissionResult.DENIED_PERMANENTLY

        // 3. Для системных разрешений — проверяем хост, потом запрашиваем
        if (permission.isSystemPermission()) {
            val hostHas = systemPermissionDelegate.hasPermission(permission.androidName)
            if (!hostHas) {
                // Запрашиваем у пользователя от имени хоста
                val result = systemPermissionDelegate.request(permission.androidName, context)
                if (result != GRANTED) return PermissionResult.DENIED_BY_USER
            }
        }

        // 4. Показываем платформенный диалог разрешения
        val userDecision = showPermissionDialog(miniAppId, permission, context)
        permissionStore.save(miniAppId, permission, userDecision)
        return userDecision
    }
}
Пример реализации permission store
class MiniAppPermissionStore {
    private val store = mutableMapOf<String, PermissionStatus>()
    fun save(miniAppId: String, permission: MiniAppPermission, status: PermissionStatus) {
        store["${miniAppId}_${permission.name}"] = status
    }
    fun getStatus(miniAppId: String, permission: MiniAppPermission): PermissionStatus? {
        return store["${miniAppId}_${permission.name}"]
    }
}

Как пользователь управляет разрешениями?

Пользователь должен иметь возможность отозвать любое разрешение в любой момент. В настройках Super App — экран с перечнем установленных мини-программ и их разрешений:

Мини-программа: "Доставка еды"
├── Геолокация (точная) ............. ВКЛ  [переключатель]
├── Камера .......................... ВЫК  [переключатель]
├── Профиль пользователя ............ ВКЛ  [переключатель]
└── История заказов ................. ВКЛ  [переключатель]

Отзыв разрешения работает сразу — без перезапуска мини-программы. Broker при следующем вызове API вернёт PERMISSION_REVOKED, и мини-программа должна корректно обработать эту ошибку.

Почему нужна runtime проверка при каждом вызове?

Разрешения могут быть отозваны асинхронно — пока мини-программа работает. Поэтому каждый вызов платформенного API проходит через broker, а не только при инициализации:

// Вызов из JS-моста
@JavascriptInterface
fun getUserLocation(callbackId: String) {
    val miniAppId = currentMiniAppContext.id

    coroutineScope.launch {
        when (permissionBroker.checkPermission(miniAppId, MiniAppPermission.LOCATION_FINE)) {
            PermissionResult.GRANTED -> {
                val location = locationProvider.getLastLocation()
                bridge.sendSuccess(callbackId, location.toJson())
            }
            PermissionResult.DENIED_PERMANENTLY -> {
                bridge.sendError(callbackId, "PERMISSION_DENIED_PERMANENTLY")
            }
            else -> {
                bridge.sendError(callbackId, "PERMISSION_REQUIRED")
            }
        }
    }
}

Как мы гарантируем безопасность?

Каждое обращение к чувствительному API логируется: timestamp, miniAppId, permission, был ли granted или denied. Это позволяет обнаружить мини-программу, которая запрашивает геолокацию каждые 5 секунд в фоне — и заблокировать её на платформе. Наша команда имеет 8+ лет опыта в мобильной разработке и реализовала более 50 проектов с системами разрешений. Мы гарантируем, что ни одна мини-программа не получит больше прав, чем задекларировано.

Что входит в нашу работу?

  • Манифест-валидатор для проверки деклараций разрешений
  • Permission store с поддержкой перманентных статусов
  • UI управления разрешениями для пользователя
  • Интеграция с нативными API Android/iOS
  • Audit trail для мониторинга использования
  • Документация по эксплуатации и тестированию

Сроки и стоимость

Разработка системы разрешений с двумя слоями, UI настроек и audit trail занимает от 2 до 6 дней в зависимости от готовности permission store и сложности интеграции. Стоимость рассчитывается индивидуально после аудита текущей архитектуры. Свяжитесь с нами для оценки вашего проекта — мы поможем построить безопасную экосистему мини-программ.

Закажите внедрение permission broker для вашего Super App.

Android Permissions Overview

Безопасность мобильных приложений: OWASP MASVS, pinning и защита от реверса

Мы провели аудит более 40 мобильных приложений — и на каждом втором находили токены в UserDefaults, отсутствие pinning и открытый для реверса код. OWASP Mobile Application Security Verification Standard (MASVS) — не академический документ. Это чек-лист пентестера. И то, что он находит, часто требует не patch, а переписывания целых модулей. Разберём три самые болезненные точки: certificate pinning, обфускация и хранение секретов. И покажем, как их закрыть без даунтаймов на продакшне.


Почему certificate pinning ломает продакшн?

Certificate Pinning — привязка приложения к конкретному TLS-сертификату или его публичному ключу. Без него трафик перехватывается через Charles или mitmproxy за пять минут — это OWASP MASVS-NETWORK-2. Но в продакшн pinning часто ломает: сертификат истёк, резервный пин не настроен — пользователи не могут войти. Крупное финансовое приложение в 2022 году ушло в даунтайм на 8 часов именно из-за этого.

На iOS реализуется через URLSessionDelegate.urlSession(_:didReceive:completionHandler:) с проверкой SecTrust. Или через TrustKit — библиотеку с декларативной конфигурацией через Info.plist. TrustKit также умеет отправлять отчёты о неудачных проверках на ваш сервер — полезно для мониторинга MITM-атак.

На Android — network_security_config.xml:

<network-security-config>
  <domain-config>
    <domain includeSubdomains="true">api.example.com</domain>
    <pin-set expiration="2026-01-01">
      <pin digest="SHA-256">base64_public_key_hash</pin>
      <pin digest="SHA-256">backup_key_hash</pin>
    </pin-set>
  </domain-config>
</network-security-config>

Критическое правило: всегда два пина — основной и резервный. Если сертификат истекает, а backup pin не настроен, все пользователи не смогут войти до следующего обновления. Именно так ломаются production-сборки.

Ещё одна точка отказа: CDN и third-party SDK. Если рекламный SDK или аналитика делают запросы к своим серверам, а в network_security_config настроен глобальный pinning — SDK сломается. Конфигурация должна быть поддоменно-специфичной.


Как защитить данные в Keychain и Keystore?

MASVS-STORAGE-1 и STORAGE-2 — самые часто нарушаемые требования. Частая ошибка на iOS: токены авторизации хранятся в UserDefaults. Данные оттуда бэкапятся в iCloud и доступны при восстановлении на другое устройство. Токен на новом iPhone — это чужая авторизованная сессия. Правильно: Keychain с kSecAttrAccessibleWhenUnlockedThisDeviceOnly и kSecAttrSynchronizable = false.

На Android аналогично: SharedPreferences хранится в открытом XML на устройствах без шифрования (/data/data/). Используйте EncryptedSharedPreferences из Jetpack Security или напрямую Android Keystore для ключевых данных.
Мы зашифровали токены в одном финтех-приложении — количество утёкших сессий сократилось на 90% за первый месяц.


Обфускация и защита кода

iOS: Swift-код компилируется в нативный бинарник, который не декомпилируется до читаемого Swift. Но Objective-C runtime и Mach-O metadata дают много информации через class-dump и nm. Имена классов, методов, строки в бинарнике — всё видно. Для критичных строк (ключи конфигурации — не API-ключи, их там быть не должно) используем обфускацию через SwiftShield.

Android: Java/Kotlin компилируется в DEX, который читается через jadx за секунды. R8 (включён по умолчанию в release сборках) минифицирует и обфусцирует. Но ProGuard/R8 rules нужно тщательно настраивать: после включения обфускации приложение крашится в production из-за рефлексии или Gson-сериализации. Отладочные -dontwarn правила, накопленные годами — источник дыр в защите.

Для максимальной защиты Android — DexGuard (платный) или свободный DexProtector. Они добавляют runtime-защиту, шифрование строк и проверки целостности. Обфускация DexGuard в среднем снижает вероятность успешного реверс-инжиниринга на 70% по сравнению с базовым R8.


Обнаружение jailbreak и root

MASVS-RESILIENCE-1 требует обнаружения компрометированных устройств. Стандартные проверки: наличие /Applications/Cydia.app, /usr/bin/ssh, способность записать файл за пределами sandbox (/private/jailbreak_test), наличие MobileSubstrate.

Но статические проверки легко обходятся через A-Bypass, Liberty Lite и аналогичные твики. Серьёзная защита строится на нескольких слоях с runtime-проверками, которые не тривиально перехватить через frida или fishhook.

Готовые решения: IOSSecuritySuite (iOS, open source), rootbeer (Android). Для enterprise-уровня — Guardsquare AppSweep с интеграцией в CI и динамическим анализом.


Что входит в работу по безопасности мобильного приложения

Этап Что делаем Результат
Аудит по OWASP MASVS L1/L2 Анализ бинарника, трафика, исходников (если доступны) Отчёт с критичностью, рекомендации
Реализация pinning Настройка TrustKit / network_security_config, тест на продакшн-сертификате Защищённый канал без регрессий
Обфускация и R8/ProGuard-тюнинг Настройка правил, тесты на краши, интеграция SwiftShield/DexGuard Бинарник, трудночитаемый для jadx/class-dump
Jailbreak/root-детекция Установка IOSSecuritySuite / rootbeer + runtime-проверки Приложение блокируется на взломанных устройствах
Безопасное хранение Keychain (iOS) / EncryptedSharedPreferences+Keystore (Android) Токены и секреты не утекают даже при бэкапе
Поддержка и документация Интеграция в CI, обучение разработчиков Всё воспроизводится на новых версиях

Как мы реализуем защиту: кейс

Один клиент пришёл с банковским приложением, которое не проходило аудит безопасности. Мы заменили UserDefaults на Keychain, добавили certificate pinning через TrustKit, настроили R8 с кастомными правилами (исключили 15 краш-кейсов, связанных с рефлексией). Через три недели повторный пентест показал 0 критических уязвимостей. С момента внедрения — ни одного инцидента за два года.


Сроки и стоимость

  • Security-аудит по OWASP MASVS уровня L1 — от 1 до 2 недель.
  • Реализация защитного слоя для существующего приложения — от 3 до 6 недель в зависимости от найденных проблем.
  • Полный цикл «аудит + внедрение + тест» — от 4 до 8 недель.

Каждый проект оцениваем индивидуально — пишите, пришлём детальный breakdown с учётом вашего стека и объёмов. Работаем под ключ: от анализа до деплоя в сторах.


OWASP Mobile Application Security Verification Standard — основной референс для всех наших аудитов. Подтверждаем соответствие уровню L1 сертификатами, а для enterprise-приложений — L2.

Оценим ваш проект за один рабочий день после получения APK/IPA. Свяжитесь — расскажем, какие дыры закроем в первую очередь.