Безопасность мобильных приложений
Основы безопасности мобильных приложений — cleartext-трафик через зависимости, утечки через кэш скриншотов, OAuth в WebView и детект компрометации/root/jailbreak.
12 вопросов
JuniorТеорияОчень частоПочему API-ключ, поставляемый внутри бинарника мобильного приложения, считают публичным значением?
Почему API-ключ, поставляемый внутри бинарника мобильного приложения, считают публичным значением?
Всё, что лежит в пакете, уезжает к пользователю, поэтому любую строку или ключ внутри установленного приложения можно оттуда восстановить; обфускация повышает трудозатраты, но не делает значение секретным. Поставленный ключ ограничивают в правах, а запросы авторизуют на сервере.
Типичные ошибки
- ✗Считать, что обфускация или нативный код делают поставленный ключ секретным
- ✗Давать клиентскому ключу больше прав, чем нужно его функции
- ✗Позволять клиенту решать, что именно разрешено запросу
Уточняющие вопросы
- →Как ограничить права клиентского ключа, чтобы утечка осталась малозначимой?
- →Где на самом деле должен жить секрет для интеграции с партнёром?
JuniorТеорияОчень частоГде мобильное приложение должно хранить токены и ключи и почему не в SharedPreferences?
Где мобильное приложение должно хранить токены и ключи и почему не в SharedPreferences?
Токены и ключи хранят в платформенном хранилище — iOS Keychain или Android Keystore: оно аппаратно защищено и требует присутствия пользователя. Файлы, SharedPreferences и plist приватны лишь пока приватно устройство, поэтому токены делают короткоживущими.
Типичные ошибки
- ✗Считать приватное хранилище приложения безопасным на root или jailbreak
- ✗Класть токены в
SharedPreferencesили plist вместо платформенного хранилища - ✗Держать на устройстве долгоживущие токены без протухания и отзыва
Уточняющие вопросы
- →Что даёт аппаратно защищённое хранилище ключей по сравнению с шифрованным файлом?
- →Как отозвать токен, который уже лежит на потерянном устройстве?
JuniorТеорияЧастоМанифест задаёт usesCleartextTraffic=false, но приложение шлёт по http. Где искать причину?
Манифест задаёт usesCleartextTraffic=false, но приложение шлёт по http. Где искать причину?
Итоговый манифест APK и network-security-config собираются из всех зависимостей, поэтому неверно настроенная библиотека может вновь включить cleartext, даже когда ваш манифест его запрещает. Проверять конфиг каждой зависимости и итог в собранном APK — настройка действует, лишь если переживает merge при сборке.
Типичные ошибки
- ✗Проверять только свой манифест, забывая про merge зависимостей
- ✗Считать, что итоговый манифест APK совпадает с исходным
- ✗Не открывать собранный артефакт для проверки финального конфига
Уточняющие вопросы
- →Как merge манифестов из зависимостей переопределяет ваш usesCleartextTraffic?
- →Почему при свёртывании приложения для ввода OTP кэш скриншота может утечь пароль?
JuniorТеорияЧастоЧто означают профили L1 и L2 в стандарте мобильной безопасности MASVS?
Что означают профили L1 и L2 в стандарте мобильной безопасности MASVS?
MASVS — стандарт мобильной безопасности OWASP, а MASTG — руководство по тестированию. L1 — базовый уровень для любого приложения: хранение, защита канала, работа с платформой. L2 добавляет эшелонированную защиту, а устойчивость к вмешательству — отдельный набор.
Типичные ошибки
- ✗Считать, что L2 заменяет базовый L1, а не дополняет его
- ✗Принимать требования устойчивости за уровень выше L2
- ✗Читать
MASVSкак сертификационный значок, а не как стандарт требований
Уточняющие вопросы
- →Каким приложениям действительно нужен профиль L2, а не базовый уровень?
- →Как руководство по тестированию
MASTGсоотносится с отдельным требованиемMASVS?
MiddleТеорияЧастоЧто даёт пиннинг сертификата поверх обычной проверки TLS и почему сложна ротация?
Что даёт пиннинг сертификата поверх обычной проверки TLS и почему сложна ротация?
TLS проверяет сервер по хранилищу доверенных корней устройства, а пиннинг сужает это до вашего ключа, поэтому ошибочно выпущенный сертификат или добавленный на устройстве CA не перехватит трафик незаметно. Плата — доступность: смена пина ломает выпущенные версии.
Типичные ошибки
- ✗Думать, что пиннинг заменяет или усиливает само шифрование TLS
- ✗Выпускать единственный пин без резервного и без плана ротации
- ✗Закреплять листовой сертификат, который меняется при каждом продлении
Уточняющие вопросы
- →Когда пиннинг оправдывает свою эксплуатационную цену, а когда нет?
- →Как резервный пин позволяет сменить сертификат без нового релиза?
MiddleТеорияЧастоЧерез какие каналы утекают данные приложения, даже если файлы хранятся правильно?
Через какие каналы утекают данные приложения, даже если файлы хранятся правильно?
Данные утекают через облачные бэкапы, логи приложения, снимки в переключателе задач и буфер обмена. Чувствительные файлы исключают из правил бэкапа, токены не пишут в логи, экран закрывают при сворачивании, а чувствительные поля помечают.
Типичные ошибки
- ✗Считать, что облачный бэкап никогда не копирует чувствительные файлы
- ✗Писать токены или персональные данные в логи релизной сборки
- ✗Игнорировать снимок в переключателе задач и буфер обмена
Уточняющие вопросы
- →Как исключить хранилище учётных данных из платформенного бэкапа?
- →Почему снимок в переключателе задач — реальная утечка для банковского приложения?
MiddleТеорияИногдаПочему биометрический запрос — локальная проверка присутствия, а не аутентификация на вашем сервере?
Почему биометрический запрос — локальная проверка присутствия, а не аутентификация на вашем сервере?
Запрос возвращает согласие на устройстве, которое вы не контролируете, а бэкенд не видит ни лица, ни отпечатка, поэтому булев ответ клиента ничего не доказывает. Запрос привязывают к ключу в платформенном хранилище и подписывают им серверный challenge.
Типичные ошибки
- ✗Отправлять на сервер булев успех биометрии как доказательство личности
- ✗Считать присутствие пользователя заменой серверной авторизации
- ✗Хранить ключ, не требуя биометрической разблокировки перед его использованием
Уточняющие вопросы
- →Что должно произойти с привязанным ключом при регистрации нового отпечатка?
- →Почему подписанный challenge доказывает больше, чем вердикт на клиенте?
MiddleТеорияИногдаЧем опасны экспортированные компоненты и кастомные URL-схемы и что делает deep link доверенным?
Чем опасны экспортированные компоненты и кастомные URL-схемы и что делает deep link доверенным?
Экспортированная activity, сервис или receiver, как и любая кастомная URL-схема, — это публичная точка входа, которую может вызвать другое приложение, а схему может заявить не одно приложение. Входящий intent валидируют и предпочитают ссылки, привязанные к домену.
Типичные ошибки
- ✗Считать, что кастомную URL-схему может заявить только одно приложение
- ✗Доверять параметрам, пришедшим внутри intent или deep link
- ✗Забывать, что компонент с intent-фильтром доступен другим приложениям
Уточняющие вопросы
- →Как проверка домена делает App Link надёжнее кастомной схемы?
- →Где на самом деле должна проверяться авторизация для экрана из deep link?
MiddleТеорияИногдаПочему детект компрометации устройства (root, jailbreak) на клиенте ненадёжен и как усложнить его обход?
Почему детект компрометации устройства (root, jailbreak) на клиенте ненадёжен и как усложнить его обход?
Собирать артефакты компрометации (файлы root, признаки эмуляции, хуки DBI), подписывать их и валидировать на сервере — нельзя доверять только клиентскому вердикту, ведь DBI-утилита Frida перехватит проверку и заставит вернуть «чисто» (как переопределяет evaluatePolicy, обходя биометрию). Обфусцировать функции детекта и тихо завершаться.
Типичные ошибки
- ✗Доверять клиентскому вердикту детекта на скомпрометированном устройстве
- ✗Кидать видимый эксепшен, указывающий атакующему на место проверки
- ✗Полагаться на единственный артефакт без подписи и серверной валидации
Уточняющие вопросы
- →Как DBI-утилита переопределяет evaluatePolicy и обходит биометрию?
- →Почему тихое завершение при детекте лучше явного эксепшена?
MiddleТеорияИногдаКакой риск добавляет сторонний SDK мобильному приложению и как его ограничивает минимум привилегий?
Какой риск добавляет сторонний SDK мобильному приложению и как его ограничивает минимум привилегий?
SDK работает внутри вашего процесса с правами приложения, его разрешениями и доступом к сохранённым данным, а поставляется под вашим именем, поэтому его дефекты и сбор данных становятся вашими. Просят только нужные разрешения, смотрят отправку и фиксируют версии.
Типичные ошибки
- ✗Считать, что SDK изолирован от данных и прав вашего приложения
- ✗Выдавать разрешение только потому, что его просит библиотека
- ✗Автоматически подтягивать версии библиотек без разбора изменений
Уточняющие вопросы
- →Как выяснить, какие данные SDK на самом деле отправляет с устройства?
- →Почему запрошенное SDK разрешение становится риском вашего приложения?
MiddleТеорияИногдаЧем список рисков OWASP Mobile Top 10 отличается от стандарта MASVS при ревью безопасности?
Чем список рисков OWASP Mobile Top 10 отличается от стандарта MASVS при ревью безопасности?
Mobile Top 10 — просветительский список повторяющихся рисков: небезопасное хранение, небезопасная передача, слабая аутентификация; он нужен для приоритетов. MASVS превращает эти области в проверяемые требования, а MASTG описывает, как проверить каждое.
Типичные ошибки
- ✗Считать Top 10 чек-листом завершённости
- ✗Ожидать от списка рисков проверяемых требований
- ✗Проверять по названию риска вместо требования
MASVS
Уточняющие вопросы
- →Как выбрать профиль
MASVSдля платёжного приложения? - →Как риск небезопасной передачи выглядит в виде проверяемого требования?
MiddleТеорияИногдаЧем опасен встроенный WebView и как ограничить его JavaScript-мост?
Чем опасен встроенный WebView и как ограничить его JavaScript-мост?
WebView исполняет удалённый контент внутри вашего процесса. JavaScript-мост открывает странице нативные методы, а доступ к файлам даёт приватное хранилище, поэтому недоверенный контент действует с правами приложения. Грузят только свой контент по TLS.
Типичные ошибки
- ✗Грузить недоверенный или http-контент во встроенном
WebView - ✗Открывать через JavaScript-мост широкие нативные методы
- ✗Оставлять включённым доступ к файлам, позволяя странице читать хранилище
Уточняющие вопросы
- →Почему методу моста нужна собственная валидация аргументов?
- →Когда вкладка внешнего браузера лучше встроенного
WebView?