Мобильное приложение всегда оказывается на устройстве пользователя — а значит, потенциально доступ к нему может быть и у злоумышленника. Это значительно повышает требования к безопасности выпускаемых продуктов, поскольку в коде приложений неизбежно содержатся конфиденциальные данные, которые используются разработчиками. Соответственно, обязательным условием становится защита секретов на клиенте от утечек.
Привет, Хабр. Меня зовут Кирилл Смирнов.
Я Технический лидер iOS команды СберЗдоровья — MedTech компании №1 в России.
В этой статье я расскажу, где в iOS-приложениях хранятся секреты и как их находят, почему важно скрывать секреты, и как выстроить надежную защиту с учетом потенциальных угроз.
Материал подготовлен по мотивам моего доклада на Podlodka iOS Crew. Вы можете посмотреть его здесь.
Также много интересного вместе с командой пишем тут.

Где хранятся секреты и как их находят
Под «секретами» в мобильных приложениях обычно понимают любые встроенные чувствительные данные:
API‑ключи;
токены;
приватные ключи;
пароли и другие.
Ввиду своей «чувствительности» секреты важно скрывать и всячески защищать, чтобы доступ к ним не смогли получить пользователи и злоумышленники. Вместе с тем, это требование не всегда легко выполнить — исследования показывают, что более половины приложений (например, 56% в Google Play) содержат встроенные ключи, которые можно обнаружить автоматизированными инструментами.
При этом секреты могут храниться в разных компонентах и местах приложения. Например, в iOS‑приложении они могут располагаться:
В коде. Часто ключи прописывают прямо в коде (в том числе, как
let apiKey = «секрет»), что обеспечивает лёгкий доступ злоумышленнику.В ресурсах. Секреты могут лежать в ресурсных файлах — строковых таблицах, JSONах или plist-ах в бандле приложения. Например, все нужные секреты можно упаковать в один secrets.json файл и декодить его в рантайме. При таком хранении секреты легко найти при распаковке .ipa архива.
Оба способа хранения ненадежны с точки зрения безопасности: статический анализ приложения (например, поиск строк в бинарном файле) почти наверняка найдет эти данные. Поэтому на практике ключи либо обфусцируют, либо шифруют перед упаковкой.
Почему важно скрывать секреты?
Секреты дают приложению особые права или доступ к ресурсам.
Если они утекут — злоумышленник сможет «притвориться» вашим приложением или пользователем.
При этом в результате кражи секретов злоумышленники могут реализовать сразу несколько угроз.
Злоупотребление API. Если в коде лежит API-ключ, атакующий может его достать и делать запросы к вашему backend от имени приложения. Это может привести к росту нагрузки, блокировке легальных пользователей и финансовым потерям (например, в случае использования тарифицируемых API). Как пример, злоумышленник может достать ключ для картографического API и сгенерировать миллионы запросов к картам, что приведет к значительному увеличению расходов со стороны владельца приложения.
Кража данных пользователей. Если с помощью ключа можно получить доступ к персональным данным — это сразу риск утечки чувствительной информации (например, access-token или refresh-token). Так, если токен OAuth попадет в руки злоумышленника, он сможет войти во взломанный аккаунт без пароля.
Обход бизнес-ограничений. Ключи могут давать доступ к внутренним или платным фичам. То есть, получив доступ к ключу, злоумышленник сможет получать доступ к платному контенту без оплаты, и владелец приложения будет недополучать выручку.
Компрометация интеграций. Часто в приложении лежат ключи к сторонним сервисам (карты, пуш-уведомления, аналитика). Утечка таких секретов может привести к поломке или дискредитации интеграции сервисов. Например, если будет украден ключ Firebase Cloud Messaging, злоумышленник сможет рассылать фейковые пуш-уведомления пользователям от имени компании.
Финансовые потери. Например, злоумышленник может использовать утёкший ключ платежного провайдера и проводить несанкционированные транзакции.
Репутационные и юридические риски. Утечка секретов может привести к взломам, и, как следствие, публикациям в СМИ и расследованию регуляторов. Это особенно критично в медицине, банках, финтехе.
То есть секреты — это «ключи от сейфа, где лежат деньги». И если они в коде и недостаточно защищены, то любой злоумышленник с навыками реверса сможет их достать.
Классификация потенциальных угроз
Теперь, когда мы разобрались с потенциальными рисками, определим классификацию угроз. Для этого переложим на мобильную разработку STRIDE — популярную модель оценки угроз, предложенную Microsoft, которая определяет шесть категорий рисков и отвечает на вопрос «Что может пойти не так?». STRIDE тесно используется и документируется в подходах, описываемых OWASP, где STRIDE определяет метод анализа угроз, а OWASP определяет набор практик защиты и описание угроз для мобильных приложений. То есть вместе они помогают выстроить осознанную классификацию угроз и стратегию работы с безопасностью в мобильных приложениях.
Итак, можно выделить несколько типов угроз.
Spoofing (Подмена). Злоумышленник пытается выдать себя за другого пользователя или сервер (кража учётных данных, фишинг, подделка запроса к API).
Tampering (Манипуляция). Изменение кода приложения или данных (инъекция вредоносного кода, подмена настроек, изменение параметров транзакции).
Repudiation (Отказ от ответственности). Отсутствие надёжных логов или аудита, когда после атаки нельзя доказать действия (например, спорные транзакции без журналирования).
Information Disclosure (Утечка информации). Раскрытие секретов приложения или пользовательских данных (считывание конфигурации или ключей из памяти устройства).
Denial of Service (Отказ в обслуживании). Перегрузка сервера или приложения, чтобы сделать сервис недоступным (например, DDoS на API).
Elevation of Privilege (Повышение привилегий). Получение привилегий, недоступных обычному приложению (использование уязвимости ОС или джейлбрейка для доступа к системным ресурсам).
Из этих категорий для секретов особенно актуальны следующие:
Information Disclosure (утечка данных/OWASP M1/M9), так как напрямую «бьёт» по конфиденциальности секретов;
Tampering (изменение данных/OWASP M8), поскольку «бьёт» по целостности секретов (например, изменение хранящегося ключа);
Elevation of Privilege (Повышение привилегий/OWASP M10) актуально, когда атакующий пытается получить root-доступ к хранилищам (Keychain) или кодовой базе приложения.
В статье подробнее остановимся именно на этих трех категориях.
Механизмы защиты секретов от Apple и их польза
Из коробки Apple предоставляет несколько механизмов защиты секретов.
Sandboxing
Sandboxing — механизм изоляции приложений друг от друга и операционной системы, используемый для повышения уровня безопасности устройства. То есть, каждый app запускается в песочнице, что изолирует его от файлов и ресурсов других приложений.
При этом:
у приложения есть случайно назначенный уникальный домашний каталог, и если ему нужен доступ к внешним данным, он может получить его только через системные API;
системные файлы и ресурсы также защищены от пользовательских приложений;
весь раздел операционной системы монтируется только для чтения.
Code Signing
Code Signing — механизм, который блокирует запуск измененных бинарных файлов приложения. Это именно то, для чего выпускаются сертификаты подписи и подписываются приложения на системе сборки и после компиляции.
ASLR
ASLR — рандомизация адресов кода, библиотек и стека при каждом запуске приложения. Метод предполагает, что во время загрузки расположение адресов «перетасовывается» и только после этого запускается основной процесс.
Например, атака return-to-libc пытается обманным путём заставить устройство выполнить вредоносный код, манипулируя адресами памяти стека и системных библиотек. Но ASLR затрудняет атаки, где злоумышленнику нужно знать фиксированные адреса в памяти (например, переполнение буфера и атаки с использованием возвратно-ориентированного программирования). То есть Apple по умолчанию защищает от подобных угроз.
Execute Never at ARM
DEP (Data Execution Prevention)/ Execute Never at ARM — технология, при которой память по умолчанию не позволяет одновременно запись данных и выполнение кода, то есть страницы помечаются как «только для кода» или «только для данных».
В случае необходимости динамического кода (как JIT‑компиляция JavaScript) iOS позволяет совершить ограниченное количество вызовов mmap с особым правом от Apple. По сути, Apple просто ограничивает JIT в сторонних приложениях.
Keychain и Secure Enclave
Keychain и Secure Enclave — это рекомендуемый способ хранения пользовательских паролей и токенов. Keychain защищён аппаратно (Secure Enclave) и привязан к паролю устройства и биометрии (TouchID/FaceID). Однако Keychain используется именно для данных, вводимых пользователем (или получаемых во время работы), но не для статических ключей разработки.
Более того, Keychain — это не панацея. Например, ему присущи уязвимости, построенные на базе iCloud Keychain, которые могут привести к утечке данных.
ATS и SSL Pinning
ATS (App Transport Security) — технология Apple, автоматически включающая HTTPS для защиты сетевых запросов приложений и запрещающая использование старых, уязвимых TLS-протоколов.
SSL Pinning — метод фиксации определенного сертификата или публичного ключа на стороне клиента, обеспечивающий дополнительную защиту от MITM-атак и поддельных сертификатов.
Ключевое о механизмах защиты
Каждая из упомянутых мер, реализованных со стороны Apple, повышает сложность атак:
изолированная среда сама по себе не даст приложению просмотреть чужие данные;
ASLR затрудняет предсказание адресов;
ARM Execute Never блокирует простую загрузку вредоносного кода в память;
TLS защищает от MITM, пока в ОС не внедрили зловредный самоподписанный сертификат.
Вместе с тем, подобная защита работает до тех пор, пока нет джейлбрейка. Если он есть — песочница снимается, и код-сайн можно обойти. То есть полностью полагаться на эти механизмы нельзя.
Примечание: Безусловно, на данный момент новых публичных джейлбрейков нет. Но они есть на старые ОС, и теоретически часть приложений можно восстановить через бэкап на старую ОС и провести хакерские манипуляции там.
Инструменты злоумышленника
Чтобы понимать, какие механики и решения могут применить злоумышленники при атаке на iOS-приложения, рассмотрим основные инструменты хакеров. Их можно условно разделить на три категории:
статический анализ;
динамический анализ;
сетевая атака.
Статический анализ
Используя инструменты статического анализа, можно выполнить:
декомпиляцию;
поиск строк внутри кода;
анализ кода в исходном виде и восстановление логики работы приложения.
Помимо этого, можно анализировать ресурсы, используемые внутри архива приложения.
Для удобства сведем информацию об инструментах в таблицу.
Назначение |
Инструменты |
Краткое объяснение |
Дизассемблирование / декомпиляция |
Hopper, IDA Pro, Ghidra, class-dump, otool, swift-demangle |
Позволяют выполнять анализ бинарных файлов на уровне ассемблера, поиск строк, функций, точек вызова. Дают возможность понять структуру приложения и находить места, где работают с секретами. |
Анализ пакета |
strings, PlistBuddy, iExplorer |
Позволяют выполнять извлечение ресурсов, plist, конфигов, иконок, строк. Удобно для поиска hardcoded API-ключей и скрытых настроек |
Примечание: Больше об инструментах статического анализа можно прочитать тут.
Динамический анализ
С помощью инструментов динамического анализа мы можем подключаться к приложению в рантайме: дебажить, подменять реализации функций, логировать используемые данные приложения. Также можно анализировать память приложения.
Назначение |
Инструменты |
Краткое описание |
Патчинг и Runtime-хукинг |
Frida, Objection, Cydia Substrate, Cycript |
Позволяют осуществлять перехват и подмену функций в рантайме, логирование аргументов (например, ключей). |
Отладка и пошаговое выполнение |
LLDB |
Штатный отладчик Xcode, который используется и для реверса. |
Дамп бинарных файлов |
Clutch, Frida-dump |
Позволяет проводить дешифровку зашифрованного бинарного файла уже после его загрузки. |
Дамп памяти |
memdump, Frida-trace |
Может применяться для извлечения расшифрованных строк и секретов из памяти. |
Сетевая атака
При выполнении определенных условий инструменты сетевого анализа позволяют подключиться, как MITM, и слушать данные, отправляемые из и внутрь приложения.
Назначение |
Инструменты |
Краткое объяснение |
Перехват HTTPS-трафика |
Charles Proxy, mitmproxy, Burp Suite |
Позволяет осуществлять перехват, просмотр и модификацию запросов/ответов приложения. |
Обход SSL Pinning |
SSL Kill Switch 3, Frida-скрипты |
Может применяться для отключения проверки сертификатов, чтобы MITM-прокси мог расшифровывать трафик. |
Анализ соединений |
Wireshark |
Подходит для низкоуровневого анализа пакетов. Используется реже, но полезен для нестандартных протоколов. |
Пример цепочки атаки на секреты в iOS-приложении
Чтобы понимать, как хакеры могут использовать возможные уязвимости и способы атак, рассмотрим типовую последовательность действий злоумышленника, потенциально используемый стек и методы обхода стандартных средств защиты.
Примечание: В рамках статьи мы будем рассматривать идеальные условия для злоумышленника, чтобы продемонстрировать все возможные риски и уязвимости.

Jailbreak устройства
Атакующий устанавливает jailbreak (например, checkra1n, unc0ver, palera1n, Dopamine). Таким образом, он снимает защиту sandbox, разрешает root-доступ (в случае rootful) и использование отладчиков/инжекторов кода. В результате киберпреступник получает возможность работать с любым процессом, ведь не без труда, но ASLR и CodeSign на взломанном устройстве можно обойти.
Доступ к .ipa
Атакующий скачивает приложение из App Store или получает .ipa через iTunes, Apple Configurator или другие механизмы доставки. Далее на jailbroken-девайсе можно «слить» установленное приложение. В итоге на руках у злоумышленника появляется полный пакет приложения.
Дешифровка бинарного файла
Все приложения из App Store шифруются DRM-слоем (FairPlay). Используя Clutch / frida-ios-dump, атакующий может «снять» этот слой и получить возможность работы с реальным Mach-O бинарем. То есть, после этого он может анализировать код, как если бы он был собран локально.
Анализ кода и ресурсов
Используя Hopper, IDA Pro, Ghidra злоумышленник может осуществлять декомпиляцию и дизассемблирование для анализа кода. Например, можно:
посмотреть вызовы интересующих фреймворков, проверить алгоритмы обработки данных внутри приложения;
проанализировать ресурсы: посмотреть в .plist, .json, .bundle, базы данных, проверить, нет ли токенов или endpoint-ов.
Инъекция кода и логирование
Используя Frida, Objection, Cydia Substrate, Cycript или другие фреймворки, атакующие могут:
вставить хуки внутрь кода;
вывести расшифрованный секрет в лог;
подменить возвращаемые значения функций;
логировать сетевые запросы до шифрования/после расшифровки.
Переупаковка и подпись
После модификации бинарный файл переупаковывается в новый .ipa.
Code Signing проверка обходится либо с помощью ldid (переподпись на устройстве), либо посредством отключения amfid (App Store verification daemon). В итоге «взломанное» приложение атакующий может снова поставить на iOS-устройство атакуемого пользователя.
Запуск и отладка на устройстве
С помощью LLDB злоумышленник подключается к процессу. Здесь атакующий может ставить брейкпоинты на ключевых методах (например, вызовы CryptoKit или deobfuscation-функции). Если атака тщательно подготовлена, к этому моменту ASLR уже «прозрачен» — LLDB показывает реальные адреса после ребейзинга.
Анализ памяти
С помощью memdump, плагинов LLDB, Frida-скриптов или других инструментов киберпреступник может просканировать память процесса на предмет «подозрительных» строк, например, API-ключей или JWT-токенов. Даже если ключ был зашифрован в бандле, после деобфускации его можно поймать в памяти в рантайме.
Анализ передачи данных по сети
Анализ передачи данных по сети реализуется с помощью mitmproxy, Charles Proxy, Burp Suite или других инструментов. Если нет SSL pinning, можно подменить сертификат и увидеть трафик в открытом виде. Вместе с тем, даже с SSL pinning злоумышленник на jailbreak-е может хукнуть вызовы URLSession/NSURLConnection и вытащить секреты до TLS или использовать механизмы отключения TLS.
Что это значит
Продемонстрированный сценарий наглядно показывает, что практически любое статически зашитое значение (ключ, пароль, токен) в iOS-приложении рано или поздно может оказаться в руках атакующего. Поэтому защита должна базироваться на:
эшелонированных мерах безопасности;
использовании секретов с ограниченным временем жизни;
минимизации количества секретов, попадающих в клиент.
Главная задача — увеличить стоимость атаки, то есть нужно не ограничиваться базовыми методами Apple, но и применять дополнительные практики. На них остановимся подробнее.
Дополнительные практики защиты
Стандартных методов защиты недостаточно для серьезного приложения, поэтому нужно строить систему безопасности самим, поверх того, что делает Apple. Для этого можно применить множество мер. Выделю некоторые.
Время жизни секрета. Желательно использовать короткоживущие токены. Чем меньше времени секрет валиден, тем меньше окно для атаки. Например, после первичного использования токена его можно отозвать, генерируя новый.
Ротация ключей и алгоритмов. Стоит регулярно заменять ключи шифрования и устаревшие криптоалгоритмы. Это ограничивает время использования скомпрометированного ключа. По мнению экспертов, хранение ключей на сервере с возможностью их заменять — лучший подход.
Деривация ключей. В некоторых подходах ключ шифрования не хранится вообще, а вычисляется «на лету» из известных атрибутов (например, из Bundle ID), часто с добавлением соли. Это позволяет не хранить пароль в чистом виде и получать ключ определенного формата (сильный ключ), который требуется для конкретного криптографического алгоритма, например, ключ для шифра AES. Но без надёжного секрета на стороне сервера подобные «доморощенные» схемы малополезны.
SSL-пиннинг. Лучшая практика — фиксировать сертификат или публичный ключ сервера в приложении, чтобы предотвратить MITM-атаки на HTTPS. При пиннинге приложение жёстко связывает домен с известным сертификатом/ключом, и любое отклонение (например, подменённый сертификат) приведёт к отказу соединения.
Фильтрация логов. Выводить секреты в логи недопустимо. Согласно рекомендациям Google, выводить можно лишь фиксированные константы, чтобы в продакшен‑сборку случайно не просочилась секретная информация. При этом важно использовать разные уровни логирования и удалять отладочные логи из продакшен‑билдов. В этом помогает система логирования osLog или Logger после iOS 14.
Детектирование джейлбрейка. Хотя защита устройства не стопроцентная, можно пытаться обнаруживать взлом (существуют библиотеки проверки песочницы, ассерты команд jailbreak, признаки дебаггера и другие методы) и при обнаружении повышенной опасности ограничивать функционал или блокировать работу.
Обфускация кода. Переименование методов/переменных и перемешивание потока управления усложняют реверс. Важно понимать, что имена методов и переменных можно обфусцировать, что скроет логику, но это не защищает сами секреты от обнаружения.
Сгруппировав меры, можно получить три линии защиты:
управление ключами;
маскировка;
контроль среды.
Теперь подробнее остановимся на некоторых описанных методах.
Обфускация vs шифрование ключей
Для защиты секретов внутри кода можно использовать обфускацию и шифрование.
Обфускация — процесс намеренного искажения, сокрытия или преобразования исходных данных таким образом, чтобы затруднить понимание их содержания или структуры посторонними лицами. То есть, обфускация предполагает простую «маскировку» значений, например, с помощью:
разделения строки (
"api_" + "key123");хранения в base64 или hex;
XOR с константой.
При этом секрет остается в приложении, но в неудобном для чтения виде, что не дает нам криптографической стойкости.
В свою очередь, шифрование подразумевает преобразование данных с использованием ключа, в результате которого восстановление секрета без ключа расшифровки невозможно.
Само шифрование может быть:
асимметричным (RSA/ECC), которое использует отдельные ключи для шифрования и дешифрования;
симметричным (AES), которое использует один общий ключ.
При этом, хоть симметричное шифрование и требует предварительного безопасного и надежного обмена ключом обеими сторонами, этот метод значительно проще и производительнее асимметричного шифрования. Поэтому «большие данные» лучше шифровать и дешифровать симметричными алгоритмами, а шифрование с открытым ключом использовать для передачи симметричных ключей.
Так, если обмен симметричным ключом может быть реализован с помощью криптографии с открытым ключом, алгоритм сводится к простым действиям:
Клиент генерирует пару ключей.
Клиент отправляет серверу свой открытый ключ.
Сервер генерирует симметричный ключ, шифрует его с помощью открытого ключа клиента и отправляет его клиенту.
Клиент расшифровывает симметричный ключ, используя свой закрытый ключ.
Теперь и клиент, и сервер имеют один и тот же общий симметричный ключ, который они могут использовать для быстрого шифрования и дешифрования.

Таким образом, шифрование даёт строгую математическую защиту (при условии безопасности алгоритма и ключей), тогда как обфускация лишь усложняет задачу анализа, но не делает данные «криптографически невосстановимыми».
Примечание: Далее в статье мы будем рассматривать использование симметричного алгоритма шифрования AES-GCM.
Идеальный жизненный цикл ключа
Чтобы обеспечить надежную работу с ключами шифрования, криптографический ключ должен проходить через несколько фаз:
генерация;
доставка в приложение (защищенная от реверса);
краткое использование в рантайме;
обнуление в памяти;
ротация.
Примечание: Мы осознанно пока не рассматриваем вариант с сервером, а ограничимся созданием и «вшитием» пароля на этапе компиляции (специфичный способ доставки).
В приложении, где секреты хранятся в коде и нет сервера для генерации и передачи ключей, это может быть реализовано следующим образом:
Генерируется пароль.
На этапе сборки этот пароль используется для генерации сильного ключа шифрования для шифрования данных на этапе компиляции. Далее пароль обфусцируется и «вшивается» в приложение вместе с инструментом шифрования.
Примечание: Плюс в том, что ничего никуда не нужно передавать — всё происходит на одном компьютере. Но нужно подумать над выбором метода обфускации.
При запуске приложения секретный пароль восстанавливается (деобфусцируется), на его основании генерируется ключ шифрования, который используется для расшифровки секретов, и затем по возможности не хранится дольше, чем нужно в оперативной памяти.
По мере необходимости можно повторно генерировать и заменять пароль (ротация) — например, при выпуске новой версии приложения или по расписанию, чтобы старый ключ устарел и мог быть безопасно удалён.
Пример реализации описанных вариантов собственными средствами
Для наглядности рассмотрим синтетический пример того, как можно реализовать все описанные идеи собственными средствами. Подобную реализацию мы уже тестировали в своих проектах на определенных этапах зрелости и она показала высокую эффективность.
В рамках примера будем использовать модульный подход через Tuist. Определим:
CryptoFramework — фреймворк, который инкапсулирует логику работы с шифрованием и раскрывает вовне утилиты для обфускации ключа (Swift макрос @Obfuscate для строк). В нём находятся обёртки над CryptoKit (для шифрования/дешифрования файлов).
CryptoCLI — консольная команда на Swift (ParsableCommand) для пост‑билд скрипта. Она берёт исходный secrets.json, шифрует его симметричным алгоритмом (AES-GCM) с помощью ключа из CryptoFramework и генерирует зашифрованный файл для приложения.
CryptoMacros — макрос, который на этапе компиляции превращает явную строку пароль в обфусцированное выражение. Это скрывает пароль даже в скомпилированном коде.

При генерации проекта мы добавляем post build action с шифрованием на сборку, где CLI‑инструмент находит secrets.json, шифрует его и кладёт в приложение. При этом в коде остаётся только обфусцированный приватный ключ и вызовы для дешифровки.

При старте приложения мы с помощью рантайм вызовов восстанавливаем пароль (деобфусцируем строку), а затем вызываем функцию расшифровки, которая читает файл из бандла, дешифрует его и декодирует в модель Swift через Decodable для дальнейшего использования.
Это решение позволяет не хранить секреты в явном виде в приложении и использовать стандартную библиотеку (CryptoKit) без сторонних зависимостей.
В перспективе развития решения можно размышлять над добавлением защиты приватного ключа через ассиметричное шифрование, которое обсуждали ранее, чтобы ключи/пароли не хранить в коде и еще больше усложнять жизнь реверс-инженеру.
В таком случае всё будет сведено к следующему алгоритму:
клиент генерирует пару ключей для защиты ключа шифрования;
отправляет на сервер публичный ключ;
сервер шифрует симметричный ключ для шифрования открытым ключом и отправляет на клиент;
клиент дешифрует приватным ключом ключ для шифрования;
и полученный симметричный ключ используется для шифрования данных на этапе компиляции и дешифрования данных в рантайме.

От общего к частному: пример подхода нашей команды к работе с секретами
Предусмотреть алгоритмы защиты секретов и выработать механики иногда бывает недостаточно — чтобы команда четко применяла их в своей работе, нужно ввести строгие регламенты и проверки.
Например, мы в своей практике используем комплексный подход, который строится на применении сразу нескольких методов.
Политики и инструкции. Разработаны внутренние правила для работы с секретами: запрещено оставлять константы с ключами в коде, нужно использовать методы их сокрытия. Эти правила доведены до сведения всех команд.
Модульный аудит (Module Assessment). Каждый модуль приложения проходит ежеквартальную проверку на предмет утечек секретов. В чек-лист таких ревью включен пункт «отсутствие секретов/паролей в коде» (аналог CI/CD SAST правил).
Code-ревью чек-лист. При ревью кода разработчики и ревьюверы должны проверять: не добавлен ли новый секрет, правильно ли используется шифрование, нет ли логирования секретов. Мы добавили пункт «секреты» в шаблон pull request, то есть каждый pull request проходит двойной ручной контроль по этому критерию.
Статический/динамический анализ. В CI/CD интегрированы сканеры (например, в нашем случае это Stingray или аналоги), которые анализируют изменения кода на предмет известных шаблонов API-ключей и паролей. Они автоматически ищут «вшитые пароли», слабые шифры и другие уязвимости в бинарных файлах и исходниках. По данным GitGuardian, автоматическая проверка на любом этапе жизненного цикла приложения помогает ловить секреты раньше.
AI Code Review и MA Agent. Мы внедрили AI-агенты код-ревью и модуль-ассессмета, которые анализируют код с потенциальными рисками, в том числе по работе с секретами, основываясь на вышеупомянутых регламентах, подсвечивают риски и потенциальные варианты решения.
Техническое проектирование. При проработке новых фич обязательно оцениваются риски работы с секретами. В Data Flow Diagram указывается, где и как генерируются, хранятся и защищаются чувствительные данные. Это помогает не упустить в анализе угроз того, что мы прописывали.
Таким образом, мы полностью регламентируем работу с секретами и делаем любое взаимодействие с ними предельно управляемым.
Главное по теме
При разработке всегда важно учитывать, что отказаться от хранения секретов на клиенте даже при всех возможных рисках зачастую невозможно. Поэтому их защиту от взлома и утечек важно тщательно прорабатывать.
Безусловно, защита секретов чисто клиентскими методами очень ограничена, но грамотное сочетание мер (обфускация кода, шифрование конфигураций, проверка среды выполнения и частая ротация ключей и алгоритмов шифрования), а в идеале и добавление удаленной стороны, обеспечивающей помощь в защите секретов, существенно повышает сложность атаки.
При этом важно помнить, что защита приложения и секретов — непрерывный процесс, который требует эволюционирования используемых методов соответственно росту потенциальных угроз со стороны злоумышленников. В таком случае вероятность утечки секретов будет сведена к минимуму.
dkfbm
Недавно писал здесь: упрятывание ключей API в коде, их размещение в секретных репо и т.п. не имеет ни малейшего смысла. Всё равно они элементарно сниффятся с использованием легальных, общедоступных инструментов. Упомянутая в статье привязка к конкретному сертификату сервера могла бы помочь, но имеет очень ограниченную область применения: сертификаты имеют ограниченный срок действия, а заставить всех клиентов обновить приложения после истечения этого срока мы не можем, с высокой вероятностью они просто решат, что приложение сломалось и перестанут им пользоваться. А с внешними сервисами типа того же firebase это в принципе невозможно, мы ротацию их сертификатов не контролируем.
Применение ключей API – всего лишь первый, самый базовый уровень защиты. Аутентикация и разграничение доступа должны обеспечиваться совсем другими средствами.
Cmuphobk Автор
Добрый день. Спасибо за комментарий.
Cmuphobk Автор
Не могу согласиться полностью.
SSL-pinning, тоже можно организовать с доставкой со статического сервера pinning-ключей/сертификатов с поддержкой CRL и шифрования/подписи пересылаемых конфигов.
Как замечается в статье, сломать можно всё.
Вопрос целесообразности и сложности.
Совокупность механик защиты помогают.
Если вы, про передачу ключей до конечных сервисов, не дать снифить, джейлбрейкать свое приложение можно, опять же до определенных границ, желаний и обширности/глубины знаний о поломке ваших методов защит.
P.S.: По истории с отлетающим приложениям, если нет remote-доставки pinning информации: механизмы форс/софт апдейтов существуют для миграции пользователей (дальше опять тонкости реализации и тд).