Безопасная отладка вашего приложения в продакшене

12 января 2023

Джеймс Шерлок
Создано 31 декабря


Production (продакшен, прод) - версия продукта, прошедшая все стадии тестирования и выложена онлайн / установлена клиенту.

Проведите пальцем вверх, проведите пальцем вниз, покружитесь и постучите ногой в ритме “Макарена”. Теперь у вас есть доступ к ✨ секретному меню разработчика ✨.

Некоторые из самых ранних известных чит-кодов и секретных меню отладки относятся к 1980-м годам, но с учетом современных технологий и безопасности — какой вариант лучше всего подходит для вашего приложения?

Debugging in Production

Как инженеры, мы тратим так много времени на создание наилучшего опыта, который только можно вообразить, для пользователя; но как много времени уходит на то, чтобы упростить выполнение цикла для нас? Хорошо разработанное меню отладчика может сэкономить часы на тестировании новых функций или устранении существующих ошибок.

Возможности бесконечны, они ограничены только вашим воображением и усилиями, которые вы готовы приложить. Изменение переключателей функций, сброс кешей, смена среды разработки, просмотр логов или текущего состояния — вот лишь несколько идей того, чего можно достичь.

В Sidetrack наше меню отладки в приложении позволяет нам быстро просматривать отдельные кэшированные сообщения, которые используются для проецирования последней служебной информации. Поскольку одно вью в нашем приложении может представлять собой сумму 100 различных сообщений, одна ошибка в начале цепочки может быстро привести к отображению неверной информации во многих местах.

Но где живет меню отладки и кто должен иметь к нему доступ? В зависимости от ваших личных факторов риска, типа проблем, с которыми вы обычно сталкиваетесь, и ваших методов разработки, вам может пригодиться одно или несколько решений из этого поста.


Варианты на выбор


Симулятор и Отладочные Сборки

Используя директивы компилятора, вы можете определить код, который не должен компилироваться в определенные сборки вашего приложения.

Например, #if DEBUG гарантирует, что обернутый код не будет включен в релизные сборки вашего приложения. Аналогично, #if targetEnvironment(simulator) будет компилироваться только когда таргетом сборки вы назначаете свой iOS-симулятор.

Это очень простое решение, и у конечных пользователей нет возможности получить доступ к этой функции, поскольку ее просто не будет в их версии приложения. Однако, если ваша цель — получить доступ к меню отладки в продакшене, этот вариант не поможет.

Когда SwiftUI был выпущен в начальной стадии, превью были заключены в директиву #if DEBUG, чтобы они не раздували двоичный файл App Store. Начиная с Xcode 11 Apple делает это автоматически. Аналогично, такие инструменты, как FLEX и Inject, отключают определенные функциональные возможности при компиляции для релизных сборок, демонстрируя хороший пример использования.

 

TestFlight

Проверив URL-расписку в App Store, можно определить, была ли установлена сборка вашего приложения через TestFlight. Это может быть полезно для включения возможностей отладки для определенных подписанных пользователей.

Однако нет различий между внутренними группами TestFlight и различными внешними группами TestFlight (что может означать предоставление доступа к большей группе, чем вы предполагали). Кроме того, это решение не работает для приложений Catalyst или приложений, распространяемых через TestFlight для macOS. Он официально не поддерживается Apple и может отказать в любой момент.

Вы можете рассмотреть возможность создания отдельной конфигурации сборки TestFlight. Это позволит вам использовать директивы компилятора (похожие на #if DEBUG) и создавать специальные сборки только для TestFlight. Вы можете отправлять разные сборки разным группам, что даст вам полный контроль.

Однако это приводит к большим накладным расходам, и можно легко случайно отправить в App Store не ту сборку. Подобное наблюдалось неоднократно ранее, даже самой Apple, которая много раз случайно отправляла сборку, содержащую инструменты разработчика, в открытый доступ.

 

Жесты

Жесты — это искусство скрывать функциональность на виду, просто за счет незаметности. Пользователи привыкли к некоторому количеству жестов, но вы определенно можете назначить дополнительный шаг для разблокировки меню отладки, если пользователь знает правильную комбинацию.

Konami Code — это чит-код, состоящий из последовательности 10 нажатий кнопок, ставший популярным в 1980-х годах благодаря игре Contra, ввод которой давал игроку 30 дополнительных жизней. В настоящее время он был адаптирован для мобильных устройств с использованием жестов смахивания. Есть много библиотек с открытым исходным кодом, обеспечивающих такое поведение — я знаю это, потому что, если вы проверите страницу благодарностей с открытым исходным кодом ряда крупных приложений, вы можете просто найти ссылку на нее.

Жесты вполне могут выполнять свою работу, но они небезопасны и на них можно легко наткнуться. Если вы используете их, пожалуйста, подумайте о пользователях невизуальных вспомогательных технологий и о том, как это может повлиять на их работу.

 

Схемы URL и Вводы Текста

Определить пользовательскую схему URL в iOS так же просто, как добавить пару строк в ваш Info.plist и обработать URL в файле AppDelegate или блоке onOpenURL в SwiftUI. Если у вас есть поле ввода текста, например строка поиска, вместо URL вы можете использовать его значение.

Это позволит тестовому пользователю ввести URL, например sidetrack://super-secret-debug-menu, в приложение, такое как Safari, и ваше приложение предоставит ему доступ к меню отладки.

Однако подобные секретные строки и URL-адреса могут быть легко обнаружены, если пользователь достаточно решителен. Например, в приложении iOS Phone есть несколько обнаруженных номеров, при вызове которых открывается доступ к скрытым функциям.

 

Тестовые Аккаунты

Если ваше приложение поддерживает вход в систему, вы можете обнаружить, что использование этой системы — отличный способ разблокировать функции отладки для определенных пользователей. Это может быть достигнуто либо путем жесткого кодирования идентификаторов пользователей в приложении (что потребует изменения в релизной версии приложения), либо путем добавления нового параметра в отклик профиля пользователя (однако опасайтесь достоверности отклика!)

Часто это может быть очень простой вариант, построенный поверх существующей функциональности. Однако не у всех есть возможность входа в их приложении, а в  действительности, вы все равно можете захотеть получить доступ к меню отладки, когда вы не вошли в систему.

 

Доверенные Профили (Наше Решение)

Решение, к которому мы пришли в Sidetrack, заключалось в использовании профиля конфигурации. Это особый вид сертификата, который можно создать с помощью Keychain Access и установить на свои мобильные устройства в качестве пользовательского профиля. Затем ваше мобильное приложение может определить наличие этого пользовательского профиля, проверив файл сертификата, встроенный в двоичный файл приложения.

Несмотря на небольшое усложнение, это позволяет решить все основные проблемы, возникающие при использовании других вариантов. Пользователь не может случайно наткнуться на это, и это не требует никакой существующей функциональности в вашем приложении. Он работает как с отладочными, так и с релизными сборками, независимо от того, где и как они распространяются.

Больше всего мне нравится то, что один и тот же сертификат можно использовать на неограниченном количестве устройств и приложений. Это идеально подходит как для независимых разработчиков, так и для компаний, которым нужно единое решение, которое работает для всех их продуктов и команд.

Вы также можете настроить несколько сертификатов, разблокировать различные уровни привилегий или указать даты истечения срока действия для подрядчиков или гостей, которым нужен доступ только в течение установленного периода времени.

Но как именно это работает? Что ж, он опирается на основу безопасности Apple, а точнее на функцию SecTrustEvaluate, которая позволяет нам оценить, доверяем ли мы данному сертификату (профилю, который загружается из двоичного файла приложения). Поскольку сертификат использует пользовательский центр подписи, это значение будет истинным только в том случае, если на устройстве установлен специальный профиль конфигурации, который мы генерируем отдельно и который связан с центром подписи. Только соответствующий профиль приведет к успешному выполнению кода.

В этом Gist мы предоставили пошаговые инструкции о том, как создавать собственные профили и сертификаты с кодом Swift, необходимым для подтверждения доверия. Мы также работаем над инструментом командной строки с открытым исходным кодом, чтобы сделать его доступным для всех, так почему бы не отметить наш репозиторий и не следить за уведомлениями о будущих обновлениях?

 

Другие варианты

Мы понимаем, что это не исчерпывающий список. В ходе нашего исследования мы выявили множество других решений, в том числе:

  • Пароль или PIN-код запрашиваемый при открытии меню отладки
  • Разблокировка меню отладки с помощью удаленного push-уведомления
  • Проверка определенных метаданных устройства, таких как имя или адрес подключенного WiFi
  • Использование общей связки ключей или группы пользовательских настроек по умолчанию, а также другого приложения, установленного на том же устройстве.

Мы будем рады услышать ваши отзывы, возможно, есть решение, которое мы не рассмотрели, или вы узнали здесь что-то новое. В любом случае вы можете связаться с нами через наш Twitter.

Содержание