Приложение не использует функции защиты от переполнений
![]() |
Критичность: СРЕДНИЙ |
| Способ обнаружения: SAST, NETWORK |
Описание
Платформа iOS предоставляет несколько способов защиты от эксплуатации уязвимостей, связанных с переполнениями. Отключение или неиспользование предложенных средств защиты может привести к возможности более простой эксплуатации уязвимостей.
Хотя в Xcode по умолчанию включены все функции защиты, рекомендуется дополнительно проверить параметры компиляции.
Возможно использование следующих функций:
-
ARC — автоматический подсчет ссылок (функция управления памятью), при необходимости добавляет сообщения о сохранении и освобождении;
-
Stack Canary — помогает предотвратить атаки переполнения буфера;
-
PIE — Position Independent Executable — включает полную ASLR.
Рекомендации
Ниже представлено описание каждого из способов защиты и описаны риски, которые могут появиться из-за их отключения.
Automatic reference counting
Automatic reference counting (автоматический подсчет ссылок) — отслеживание и управление памятью вашего приложения. В большинстве случаев это означает, что управление памятью «просто работает» и не нужно думать о самостоятельном управлении памятью. ARC автоматически освобождает память, которая использовалась экземплярами класса, когда эти экземпляры больше не нужны.
"Targets" > "Build Settings“ > "Objective-C Automatic Reference Counting" = “YES”
Stack smashing protection
В ipa-архиве собранного приложения хранится исполняемый бинарный файл формата mach-o. Он содержит следующие секции: статической информации приложения (текст, константы и т. д.), исполняемого кода, включенных статических библиотек и списка динамически подгружаемых ресурсов. Наряду с таблицей разбиения и положения (адресов) этих секций присутствует область данных с флагами этапа компиляции и особенностей его работы для загрузчика ОС.
Одним из них является флаг режима защиты приложения от переполнения стека и перехвата управления. Так же он называется canary-protection (канареечная защита) и заключается в добавлении битовых флагов на границах фрейма стека. При попытке выйти за границы стека и перезаписать адрес возврата из функции произвольным значением перезапишется и сам сигнальный бит, о чем будет оповещена ОС и процесс приложения будет остановлен.
Режим компиляции с защитой стека от переполнения задается средой IDE Xcode, в меню настройки компиляции и задается директивой “-fstack-protector-all“.

Опция ‘OTHER_CFLAGS = "-fstack-protector-all"’ является обязательной для проектов на C / C++ / Objective-C — языков с ручным управлением памятью.
Ручной анализ
Проверить наличие данного режима в собранном приложении можно распаковав ipa-архив и проанализировав хранящийся в нем бинарный файл утилитой “otool” на наличие данной настройки. Для этого можно использовать следующую команду:
otool -Iv DVIA | grep stack

На изображении можно видеть наличие признаков защиты стека.
Так же можно воспользоваться утилитой objection и получить более подробную информацию.

Особенности Swift приложений
Swift — это язык со строгой статической типизацией и встроенной проверкой границ при доступе к массивам и коллекциям. Важно понимать, что эта проверка границ выполняется преимущественно в рантайме, а не на стадии компиляции: при выходе за пределы массива программа аварийно завершается контролируемым образом (runtime trap), что не даёт перезаписать соседние области памяти. Именно поэтому классический stack canary в чистом Swift-бинаре теряет смысл, и компилятор не оставляет соответствующий флаг защиты стека в бинарном файле.
Важно
Для проектов, написанных только на Swift, флага защиты стека в итоговом бинарном файле не будет — для исполняемых файлов, написанных на чистом Swift, он не имеет смысла.
Swift не отменяет проблем безопасности памяти
Безопасность памяти в Swift не абсолютна. Гарантии действуют только для «безопасного» подмножества языка. Они не распространяются на:
- API из семейства
Unsafe*(UnsafePointer,UnsafeMutableBufferPointer,withUnsafeBytesи т. п.) — здесь проверки границ за разработчиком; - взаимодействие с кодом на C / C++ / Objective-C (C-interop), импортированными библиотеками и системными вызовами;
- целочисленные переполнения при использовании «маскирующих» операторов (
&+,&*,&-), которые намеренно не диагностируются.
Поэтому при наличии C-interop или Unsafe*-кода уязвимости переполнения по-прежнему возможны, и средства защиты (stack canary, ASLR/PIE) остаются актуальными.
В свете вышесказанного для достоверного определения включенного режима защиты стека от переполнения необходимо проанализировать исходный код Xcode-проекта и его настроек компиляции, в разделе указанном выше, а в случае возникновения срабатывания на этом флаге определить, используется ли при разработке Objective-C, C/C++ или Unsafe*-конструкции Swift.
ASLR (Address space layout randomization)
Рандомизация размещения адресного пространства — технология, при использовании которой случайным образом изменяется расположение в адресном пространстве процесса важных структур данных, а именно образов исполняемого файла, подгружаемых библиотек, кучи и стека.
Технология ASLR создана для усложнения эксплуатации нескольких типов уязвимостей. Например, если при помощи переполнения буфера или другим методом атакующий получит возможность передать управление по произвольному адресу, ему нужно будет угадать, по какому именно адресу расположен стек, куча или другие структуры данных, в которые можно поместить код.
"Targets" > "Generate Position-Dependent Code“ = "NO"
"Targets" > "Don't Create Position Independent Executables “ = "NO"
На картинке ниже наглядно показано, как размещаются данные приложения в памяти с использованием рандомизации и без неё:

