ПОЧЕМУ БЕЗОПАСНОСТЬ ТАК ТРУДНО ПОСТРОИТЬ

Реализация безопасности в проектах Android

Помните: невозможно обеспечить полную безопасность. Цель не в том, чтобы сделать приложение «пуленепробиваемым», а в том, чтобы максимально замедлить работу хакеров и сделать недействительными все их действия при каждом выпуске.

Тип атак и меры противодействия

Человек посередине - это прокси между вашим приложением и сервером. Перехват всех запросов и изменение данных в обоих направлениях. Примеры: замена сертификатов TLS / SSL на пользовательские, управляемые кодом прокси, и шифрование / дешифрование / повторная упаковка всех данных на стороне сервера. HTTPS может поднять планку для этих сценариев.

Как предотвратить:

  1. Привязка сертификатов (проверка сертификатов подключения к серверу). Используйте сертификаты от «известных» поставщиков, например Amazon.
  2. Прозрачность сертификатов (https://github.com/babylonhealth/certificate-transparency-android или https://github.com/google/conscrypt)
  3. Включать использованный отпечаток сертификата в тело каждого запроса (позволяет серверной стороне также проверять, что клиент не находится под контролем хакеров)
  4. Протокол динамической безопасности (в процессе связи сервер может запросить переход на новый тип шифрования / подписи / секрета / вызова)

Пропущенные компоненты:

  • Довольно часто разработчик забывает, что атака может быть начата с уровня DNS, поэтому разрешение доменного имени также должно быть защищено. Разработчики должны подумать об использовании TlsDNS или HttpsDNS с закреплением сертификатов.
  • Проверьте всю цепочку сертификатов, а не только последний (проверьте от корневого сертификата до сертификата вашей компании). Если возможно, время от времени «меняйте» сертификаты (или используйте ограниченные по времени сертификаты, действительные только в течение короткого периода времени).

Изменения структуры данных - хакеры фактически перехватывают ваше общение и теперь пытаются ввести данные, которые могут вам навредить.

Как предотвратить:

  1. Зашифровать тело всех запросов (усложнить хакерам обнаружение структур данных, используемых в вызовах API)
  2. Включать в код подтверждения тела (также известный как подписывание), который позволяет обнаруживать изменения в данных на стороне сервера (общий для oAuth1)
  3. Используйте динамические структуры данных, которые переключаются на основе ответа протокола «рукопожатия» сервера. Самый простой способ - ввести в каждую используемую структуру данных несколько необязательных полей / свойств, которые мы начинаем заполнять чем-то, вычисленным во время выполнения, и это можно легко проверить на стороне сервера.
  4. Используйте динамическое шифрование / преобразование, которое контролируется сервером, сервер в любой момент может запросить переключатель шифрования, кроме того, для переключения на другую точку входа. (Расшифровка для хакеров - очень трудоемкий процесс)

Пропущенные компоненты:

  • Защита структур данных довольно сложна, обратный инжиниринг или общедоступный API могут легко уничтожить эти меры, вы можете создавать структуры данных со многими «зарезервированными» полями, использование которых довольно скрыто в логике кода.
  • Как можно чаще используйте этапы обфускации и оптимизации, proguard может значительно изменить структуру классов и усложнить извлечение логики. Вы также можете рассмотреть dexguard, платную версию, эквивалентную proguard.

Человек против бота - хакеры автоматизируют свою работу, им нужно сделать тысячи попыток, прежде чем они найдут решение, которое преодолеет все наши «стены безопасности». Делать вещи вручную - это не способ для них.

Как предотвратить:

  1. Записывайте сеансы каждого пользователя и сравнивайте сеансы друг с другом. Если мы видим абсолютно идентичные сеансы / действия со стороны пользователя - велика вероятность, что мы увидим «бота» в действии. Человек не может повторять действия одинаково. Есть несколько компаний, которые могут помочь вашему приложению обнаруживать трафик ботов.
  2. Re-captcha. Убедитесь, что вы взаимодействуете с человеком, а не с роботом.
  3. Убедитесь, что вы действительно общаетесь с реальным устройством, а не с эмулятором. (Идентификаторы: рутированное устройство, обнаружена виртуализация, странный мобильный оператор или нет). Проверка может быть основана на протоколе OTP (One Time Pass). SMS / Push-сообщение / токен аутентификации и т. Д. С одноразовым кодом доступа.
  4. Запросы на замедление с IP-адресов, которые не принадлежат интересующим вас странам (рынки, которые вы не поддерживаете). Зачем замедляться вместо того, чтобы отрицать? Ответ короткий - люди любят путешествовать.
  5. Биометрия - используйте биометрические данные для подтверждения того, что «перед вами» находится человек, а не робот. Отпечаток пальца, собственноручная подпись и т. Д.
  6. Случайные проверки безопасности с откатом к взаимодействию с пользователем (покажите картинку с простым математическим действием и попросите пользователя решить ее)
  7. Kill-переключение на конкретного пользователя, конкретное устройство, конкретный IP-адрес страны
  8. Старайтесь избегать любых операций автоматического входа в систему. Сделать возможным отключение автоматического входа для конкретного пользователя.

Пропущенные компоненты:

  • Ложное обнаружение. Иногда пользователей принимают за роботов. Проверки добавляют трение, поэтому всегда помните о простоте. В худшем случае не разрывайте соединение, дайте пользователю возможность доказать, что это человеческое взаимодействие, откат к reCaptcha.

Спуфинг API - можно рассматривать как подтип DDoS-атаки. Хакеры пытаются создать проблемы, «съедая» ваши ресурсы / бюджеты масштабирования ИЛИ рассылая ваш API неверными данными. Под атакой могут быть ваши точки входа в API: ваш серверный API, ваши аналитические сервисы, SDK сторонних поставщиков.

Как предотвратить:

1. Скройте API client_id в коде (это должно быть секретом, но на самом деле их довольно легко найти в большинстве приложений). Лучшим подходом на сегодняшний день является использование методов «обфускации», извлекающих секрет в последний момент перед его использованием. Это предотвратит автоматическое извлечение этих секретов из вашего кода и замедлит хакеров, а также заставит их прочитать код, подвергнутый обратному проектированию.



2. Разрешить звонки только от «доверенных» клиентов. Проверяйте вызовы API на нескольких уровнях: включайте отпечаток сертификата двоичной подписи в запросы (заголовок или тело. Помните, что заголовки HTTP-запросов не зашифрованы, могут быть только значения полей). Убедитесь, что у всех вызовов есть действительный client_id.

3. Секретное вращение. Для каждого выпуска делайте ротацию / замену секрета на новое значение. Если сам секрет нельзя заменить новым, вам следует обновить методы / константы обфускации.

4. Переключатель Kill - устаревшие версии и принудительное использование клиентами последней наиболее защищенной версии приложения. (Рекомендуемое время - 90 дней)

5. Скройте весь аналитический трафик, лучший подход - направить трафик на собственный сервер, а на стороне сервера перенаправить трафик на необходимый аналитический сервер (-ы).

Пропущенные компоненты:

  • Спуфинг API - это сложнее всего предотвратить, он всегда основан на обратной инженерии кода приложения. Лучшее из того, что вы, как разработчик, можете сделать - это усложнить чтение и понимание кода.
  • React Native может иметь собственный код на нескольких уровнях: код JavaScript, Java / Kotlin и C / C ++. Внедрение шифрования / дешифрования, которое затрагивает все три уровня, сделает работу хакера чрезвычайно сложной и увеличит сложность (техническую глубину) до экстремальных уровней.
  • Ротация секретов всегда связана с «паролями» и собственными «секретами API». Разработчики довольно часто забывают о сторонних API из-за использования SDK этих сторонних поставщиков. Правда в том, что сторонние библиотеки SDK имеют абсолютно те же риски безопасности, что и ваше собственное приложение. Потеря аналитики сделает «бизнес слепым», а это может стоить больше денег, чем что-либо другое. Хакер может подделать API вашего поставщика аналитики и повредить ваши данные или даже вызвать чрезмерную реакцию со стороны поставщика (например, заблокировать проект / учетную запись на панели инструментов поставщика). Хороший подход - разделить данные аналитики между несколькими учетными записями / проектами по некоторым критериям - по платформам, по годам… что позволит минимизировать потери, если это произойдет.
  • Сохраните разные настройки тайм-аута для операций входа и выборки (доступа к данным) после аутентификации. API входа / регистрации являются наиболее частыми объектами атак.
  • Не используйте «динамические запросы» со стороны приложения. Все схемы данных запросов должны быть предопределены. Не позволяйте хакерам свободу действий (если они дошли до этой точки).

Backend защита

  1. Обнаруживать аномалии в трафике, атаки методом «грубой силы», регулировать время отклика для разных IP-адресов (стран). Сохраните экземпляры с высоким уровнем ресурсов для основных стран и один экземпляр с низким уровнем ресурсов для «не приоритетных» вещей. Атаки часто выполняются с нескольких IP-адресов, расположенных в разных странах, в худшем случае они будут DDoS-атакой только на «малоресурсный» экземпляр. Другой интересный подход - вместо 403 возврата к «источнику атаки» - «таймаутам» TCP сокет часто имеет таймауты от 30 секунд до 10 минут. Динамические таймауты позволят снизить нагрузку на серверы.
  2. Брандмауэр все запросы, которые не соответствуют вашему «отпечатку пальца» (версия приложения, заголовки, сертификаты и т. Д.)
  3. Проверьте конфигурацию на стороне сервера, удалите все СЛАБЫЕ шифры из списка разрешенных.

Защита от обратного проектирования

  1. Запутать код на максимально возможном уровне (что может усложнить тестирование приложения)
  2. Используйте все три уровня кода: JavaScript, Java / Kotlin и C / C ++. Сделайте техническую глубину очень высокой для хакеров. (я говорю о проектах React Native!)
  3. Исключить из двоичных файлов все ненужные файлы (* .properties, * .version). Не давайте хакерам никаких подсказок о том, какие версии библиотек используются.
  4. Используйте GuardedStrings для хранения «секретной» информации в памяти, скрывайте информацию от любого инструмента поиска в памяти.
  5. Используйте обфускации для кода React Native, сделайте несколько преобразований (uglify, obfuscate, randomize)
  6. Внедрить автоматическую проверку уязвимостей (https://medium.com/@appmattus/android-security-scanning-your-app-for-known-vulnerabilities-421384603fc5)

Послесловие

Реализация всех этих подходов в вашем проекте - довольно сложная задача. Поэтому, даже если у вас нет ресурсов / возможностей для реализации всех из них, помните о них при определении архитектуры и дизайна. Это сэкономит вам много времени и позволит уберечь бизнес от «неотложных» кризисов. Спасибо, что прочитали это.