Перейти к основному содержанию
Блог

Мобильные

Подготовка iOS-приложения к экспертизе: практический чек-лист

Защита от jailbreak и динамического анализа, ATS, Keychain и подготовка IPA. Что проверить перед тем, как сдавать iOS-приложение на экспертизу по кибербезопасности.

· 8 мин. чтения

Фото: www.Pixel.la Free Stock Photos, CC0 · Wikimedia Commons

iOS часто воспринимают как «безопасную платформу саму по себе». Приложения работают в sandbox, есть проверка App Store, код подписывается. Это так, но экспертиза по кибербезопасности проверяет не платформу, а именно ваше приложение. В iOS-приложении нашего собственного продукта (Flutter) экспертиза дала две находки высокого уровня: нет защиты от инструментов динамического анализа и не обнаруживается jailbreak. Обе относятся к категории M7 — Insufficient Binary Protections из OWASP Mobile Top 10 (2024).

Список ниже составлен на основе этого опыта. Он сгруппирован по разделам OWASP MASVS, поэтому его легко сопоставить с находками в отчёте экспертизы.

1. Защита от jailbreak и динамического анализа (MASVS-RESILIENCE)

На устройстве с jailbreak ограничения sandbox ослабевают: другие процессы могут читать файлы приложения, обращаться к Keychain, подменять функции приложения во время работы. А инструменты вроде Frida позволяют внедрить код (hook) в приложение и изменить его поведение даже без jailbreak.

Здесь экспертиза ожидает от приложения:

  • обнаружения признаков jailbreak (подозрительные файлы, доступные на запись системные каталоги, магазины вроде Cydia/Sileo);
  • обнаружения подключённого отладчика;
  • обнаружения Frida и других hook-инструментов;
  • обнаружения переподписи приложения (tamper);
  • чёткой реакции на угрозу: прекращения работы или блокировки важных функций.

Мы закрыли это с помощью библиотеки freeRASP. В конфигурации для iOS указываются bundle ID и Apple Team ID — если приложение переподписать сертификатом другой команды, библиотека это заметит. При обнаружении угрозы пользователь видит понятный блокирующий экран.

Как проверить: запустите приложение на тестовом устройстве с jailbreak или с подключённой Frida и убедитесь, что появляется блокирующий экран. Экспертиза проверяет именно так.

2. App Transport Security (MASVS-NETWORK)

ATS по умолчанию блокирует на iOS незашифрованные HTTP-соединения. Проблема в том, что его очень легко отключить. В Info.plist не должно быть такого ключа:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Если какой-то внешний сервис всё ещё работает по HTTP, не отключайте ATS целиком — сделайте исключение только для этого домена (NSExceptionDomains) и задокументируйте его. В идеале исключений нет вовсе.

ATS — это только транспортный уровень. Закрепление сертификата (pinning) добавляется отдельно. В Flutter-приложении мы загрузили в Dart SecurityContext только доверенные корневые сертификаты — это одинаково работает на iOS и Android.

3. Keychain и хранение данных (MASVS-STORAGE)

Токены, сессионные ключи и персональные данные не должны храниться в UserDefaults или обычном файле — они не зашифрованы и попадают в резервную копию устройства. Правильное место — Keychain.

В Keychain важно и то, какой уровень доступности (accessibility) выбран. Для данных, которые не должны переноситься на другое устройство, используйте варианты с окончанием ThisDeviceOnly, например kSecAttrAccessibleWhenUnlockedThisDeviceOnly. Во Flutter с flutter_secure_storage:

const storage = FlutterSecureStorage(
  iOptions: IOSOptions(
    accessibility: KeychainAccessibility.first_unlock_this_device,
  ),
);

Ещё одна тонкость: на iOS записи Keychain могут сохраняться после удаления приложения. Добавьте логику очистки старых записей при первом запуске.

4. Следы внутри приложения

Экспертиза смотрит и на следы, которые приложение оставляет во время работы:

  • Логи. В release-сборке через print/NSLog не должны выводиться токены, номера телефонов или тела запросов.
  • Снимок для фона (snapshot). При уходе в фон iOS сохраняет снимок экрана. На экранах с чувствительными данными закрывайте содержимое при переходе в фон.
  • WebView. Если в приложении есть WebView, очищайте его cookie и кеш при выходе из аккаунта. Мы добавили и это.
  • Буфер обмена. Ограничьте копирование из полей пароля и кодов.

5. Защита кода

Dart-код должен собираться через flutter build ipa --release --obfuscate --split-debug-info=.... Эндпоинты и ключи не должны лежать в бинарном файле обычными строками. Эта тема подробно раскрыта в отдельной статье.

6. Коротко об export compliance

Ключ ITSAppUsesNonExemptEncryption в Info.plist — это вопрос App Store Connect об экспортном контроле. Если приложение использует только HTTPS и стандартное шифрование системы, обычно ставится false; при собственных алгоритмах шифрования может потребоваться дополнительная документация. Напрямую к экспертизе по кибербезопасности этот ключ не относится, но это тоже вопрос о шифровании, и ответы на оба не должны противоречить друг другу. Для вашей конкретной ситуации опирайтесь на официальную документацию Apple.

7. Сдача IPA-файла

  • Заранее уточните, какой файл ожидает экспертиза: какой тип сборки, с какой подписью.
  • Сдаваемый IPA должен быть собран именно с release-настройками — в debug-сборке обфускация и RASP работают иначе.
  • Экспертиза запрашивает контрольные суммы файла (MD5, SHA-1, SHA-256). Снимайте их с того самого файла, который сдаёте, и не пересобирайте его.

Короткий чек-лист

  1. Обнаруживаются jailbreak, отладчик, Frida и tamper; есть реакция на угрозу.
  2. NSAllowsArbitraryLoads отсутствует, исключения ATS минимальны и задокументированы.
  3. Настроен pinning сертификатов.
  4. Чувствительные данные — в Keychain с уровнем ThisDeviceOnly.
  5. В логах нет чувствительных данных, фоновый снимок закрыт, WebView очищается при выходе.
  6. Dart-код обфусцирован.
  7. IPA — release-сборка, контрольные суммы сняты именно с этого файла.

Сканирование

Хотите проверить iOS-приложение перед сдачей на экспертизу? Оставьте заявку на сканирование. ИИ-агент Claude и наш специалист пройдутся по пунктам выше и подскажут, какие уязвимости закрыть в первую очередь.