Основы мобильной безопасности
На телефоне «клиент» полностью в руках пользователя (и атакующего): любой секрет, зашитый в приложение, считается раскрытым.
Модель угроз мобильного приложения строится на допущении, что устройство может быть скомпрометировано (root/jailbreak), а сам APK/IPA — извлечён и разобран. Поэтому в приложении нельзя прятать секреты и нельзя доверять только клиентским проверкам. Эталон рисков — OWASP Mobile Top 10.
Мобильное приложение — это не «защищённая коробка». Файл приложения легко достать с устройства, распаковать и изучить; трафик можно перехватить; локальное хранилище на разлоченном устройстве читается напрямую. Защитнику (и разработчику) важно понять три класса проблем из OWASP Mobile Top 10 — небезопасное хранение данных, слабую защиту трафика и лёгкость реверс-инжиниринга — концептуально, без рецептов взлома чужих приложений, и закрыть их правильной архитектурой.
Зачем это знать защитнику
Разработчики часто переносят серверные привычки на клиент: «положу токен в локальное хранилище», «проверю подписку в приложении», «зашью API-ключ в код». На мобильном это не работает: всё перечисленное достаётся из приложения. Понимая это, вы проектируете так, чтобы компрометация устройства не открывала чужие данные и серверные секреты. Анализировать можно только свои приложения и легальные тренировочные APK (специальные «vulnerable apps» для обучения). Разбирать и модифицировать чужое приложение — нарушение закона (ст. 272/273 УК РФ).
Небезопасное хранение данных
Самая частая ошибка — хранить чувствительное (токены, пароли, персональные данные) в открытом виде: в SharedPreferences/UserDefaults, в обычных файлах, в логах или в локальной БД без шифрования. На разлоченном устройстве или из бэкапа это читается напрямую.
Как защититься
- Хранить минимум. Лучший секрет на устройстве — тот, которого там нет. Не кэшируйте лишнее.
- Использовать защищённое хранилище ОС. Android Keystore и iOS Keychain хранят ключи в аппаратно изолированной области; токены — в EncryptedSharedPreferences / Keychain, а не в обычных файлах.
- Не писать секреты в логи. Токены и пароли не должны попадать в журналы — их видно через системные инструменты.
# Концепция: чувствительные данные — только через защищённое хранилище ОС
Android -> Keystore + EncryptedSharedPreferences
iOS -> Keychain (kSecAttrAccessibleWhenUnlocked)
# Что НЕ хранить в открытом виде: токены, пароли, ключи, PII
Слабая защита трафика
Если приложение ходит по HTTP или принимает любой TLS-сертификат, трафик читается и подменяется в недоверенной сети. Базовая защита — HTTPS (TLS) везде, без исключений «для отладки», доезжающих до релиза.
Certificate pinning
Pinning (закрепление сертификата) — приложение доверяет не любому валидному сертификату, а только заранее заданному (вашему серверу). Это усложняет перехват трафика через подставной сертификат.
Пиннинг — это про устойчивость к перехвату, но он не панацея: на разлоченном устройстве его можно обойти инструментами анализа. Поэтому пиннинг сочетают с принципом «сервер не доверяет клиенту»: критичные проверки и авторизация — всё равно на бэкенде.
| Слабо | Правильно |
| HTTP или «доверять всем сертификатам» | HTTPS/TLS обязательно, валидация цепочки |
| секреты и логика «только в приложении» | проверки на сервере, токены — короткоживущие |
| нет защиты от перехвата | certificate pinning к своему серверу |
Реверс-инжиниринг приложения
Файл приложения можно распаковать и изучить: посмотреть строки, ресурсы, структуру кода. Цель атакующего — найти зашитые ключи, понять логику клиентских проверок (например, «премиум включён») и обойти их. Важно понять концептуально: код, доехавший до устройства, не является секретом.
Как защититься
- Никаких серверных секретов в приложении. API-ключи сторонних сервисов, которые должны быть тайной, держат на своём бэкенде, а приложение ходит к нему.
- Важные проверки — на сервере. Статус подписки, права, бизнес-правила проверяет бэкенд, а не клиент: клиентскую проверку обойдут.
- Обфускация (R8/ProGuard и аналоги) переименовывает классы/методы и затрудняет чтение кода. Это повышает порог, но не делает код секретным — рассматривайте её как дополнительный слой, а не замену серверной защите.
- Анти-tamper и проверка root/jailbreak могут усложнить запуск в скомпрометированной среде, но также обходятся; полагаться только на них нельзя.
Как это работает под капотом
Любое мобильное приложение — это клиент на устройстве, которое вы не контролируете. Хранилище приложения — это файлы в песочнице, доступные на разлоченном устройстве; трафик — это сетевые пакеты, видимые на пути; код — это упакованные классы и ресурсы, которые распаковываются. Поэтому «секрет в приложении» — это секрет, отданный пользователю. Вся оборона строится на двух идеях: чувствительное либо не хранят на устройстве, либо кладут в аппаратно-защищённое хранилище ОС; а доверенные решения (авторизация, секреты, бизнес-логика) принимает сервер, не клиент.
Как защититься
- Минимизируйте данные на устройстве; чувствительное — только через Keystore/Keychain и зашифрованное хранилище, не в логах.
- Весь трафик по HTTPS/TLS с валидацией; добавляйте certificate pinning к своему серверу.
- Не зашивайте серверные секреты и API-ключи в приложение — храните их на бэкенде.
- Критичные проверки (подписка, права, бизнес-правила) выполняйте на сервере; клиент к ним только обращается.
- Обфускация и анти-tamper — полезные дополнительные слои, но не замена серверной защите; тестируйте только свои приложения.
Итоги
- Модель угроз: устройство может быть скомпрометировано, а файл приложения — разобран; секрет в приложении считается раскрытым.
- Три класса рисков (OWASP Mobile Top 10): небезопасное хранение, слабый трафик, лёгкий реверс.
- Хранение — через Keystore/Keychain и шифрование; трафик — TLS + pinning; секреты и проверки — на сервере.
- Обфускация повышает порог, но не делает клиентский код секретным.
- Реверсить и менять можно только свои приложения и учебные APK; чужое — это ст. 272/273 УК РФ.