Главное правило мобильной безопасности: всё, что поставляется в приложении, доступно атакующему. Бинарник распаковывают, трафик перехватывают, код декомпилируют. На собесе проверяют, понимаете ли вы, что защищать на клиенте, а что только на сервере.
Секреты
Секретные ключи сторонних API (платёжные, админские) в приложение не кладут: ни в код, ни в ресурсы, ни «обфусцированными». Операции, требующие секрета, выполняет ваш сервер, а клиент получает короткоживущие токены с ограниченными правами.
Хранение на устройстве
- iOS: Keychain с подходящей доступностью (
WhenUnlocked,AfterFirstUnlock, суффиксThisDeviceOnlyзапрещает перенос в бэкап); Data Protection для файлов. - Android: ключи в Android Keystore (часто в аппаратном модуле, ключ нельзя извлечь), данные шифруются этим ключом и хранятся в файле или DataStore.
UserDefaultsиSharedPreferencesхранят данные открытым текстом: токены туда нельзя.- Пароль пользователя не хранят вообще.
- При выходе стирают всё пользовательское.
Аутентификация
OAuth 2.0 для нативных приложений (RFC 8252):
- Authorization Code + PKCE: защищает код авторизации от перехвата другим приложением;
- вход через системный браузер (
ASWebAuthenticationSession, Custom Tabs), а не WebView: приложение не видит пароль, работают сохранённые сессии; - никакого client secret в приложении;
- короткие access-токены, ротация refresh-токенов.
Биометрия должна открывать секрет (токен в Keychain с SecAccessControl, ключ Keystore с обязательной аутентификацией), а не возвращать «успех» в код: if biometricOK { login() } обходится хуком.
Сеть
- Только HTTPS: ATS на iOS,
cleartextTrafficPermitted=falseв Network Security Config на Android. - Certificate pinning защищает от MITM с подменённым доверенным сертификатом. Пинят публичный ключ (SPKI), держат запасные пины и план ротации, иначе смена ключа на сервере отключит старые версии приложения.
Целостность клиента
- Обфускация и минификация (R8 на Android): усложняет реверс, уменьшает размер, но не делает его невозможным.
- Root/jailbreak-проверки повышают стоимость атаки, но обходятся.
- Аттестация: Play Integrity API на Android (SafetyNet устарел), App Attest и DeviceCheck на iOS. Решение о доверии принимает сервер.
Утечки через платформу
- Логи с токенами и персональными данными попадают в системный журнал и крэш-отчёты.
- Превью в переключателе приложений и скриншоты:
FLAG_SECUREна Android, заглушка при уходе в фон на iOS. - Буфер обмена, клавиатуры сторонних разработчиков для полей паролей.
- Экспортированные Activity и deep links, выполняющие действия без подтверждения.
- WebView с JS-мостом: уязвимость страницы становится уязвимостью приложения. Мост только для доверенных доменов, проверка origin.
Стандарты
OWASP MASVS описывает требования (хранение, криптография, аутентификация, сеть, платформа, код, устойчивость к реверсу), а MASTG методику тестирования. Банки и финтех ориентируются на них при аудитах и пентестах.
Модель угроз
Активы (деньги, сессии, персональные данные), атакующие (вор телефона, вредоносное приложение, атакующий в сети, реверсер), меры по каналам и сервер как последняя линия: подтверждение операций, лимиты, антифрод, привязка к устройству.
Что спросят на собесе
- Где хранить токены на iOS и Android?
- Можно ли хранить API-ключ в приложении?
- Как правильно сделать OAuth в мобильном приложении?
- Что даёт certificate pinning и чем он опасен?
- Как сделать безопасный вход по биометрии?