Сейчас все больше говорят о статическом анализе для поиска уязвимостей как необходимом этапе разработки.
Однако многие люди также говорят о проблемах статического анализа.
Об этом много говорили раньше Позитивные хакерские дни , и в результате этих обсуждений мы уже писали об этом как работает статический анализатор.
Если вы пробовали какой-либо серьезный инструмент, вас, возможно, отпугнули длинные отчеты с запутанными рекомендациями, трудности с настройкой инструмента и ложные срабатывания.
Так нужен ли статический анализ? Наш опыт говорит нам, что это необходимо.
И многие проблемы, возникающие при первом взгляде на инструмент, можно решить.
Попробую рассказать, что может делать пользователь и каким должен быть анализатор, чтобы его использование было полезным и не привносило «еще один ненужный инструмент, который требуется специалистам по безопасности».
О статическом анализе
Итак, мы уже говорили о теоретических ограничениях статического анализа.Например, глубокий статический анализ пытается решить проблемы, сложность которых экспоненциальна.
Поэтому каждый инструмент ищет компромисс между временем работы, затраченными ресурсами, количеством найденных уязвимостей и количеством ложных срабатываний.
Зачем вообще нужен глубокий анализ? Любая IDE очень быстро находит ошибки, иногда даже связанные с безопасностью — какие вообще экспоненциальные проблемы? Классический пример — SQL-инъекция (или любая другая инъекция, например XSS, RCE и т. д.), которая проходит через несколько функций (то есть чтение данных от пользователя и выполнение запроса происходят в разных функциях).
Для его обнаружения требуется межпроцедурный анализ потока данных, а это задача экспоненциальной сложности.
Согласитесь, без поиска таких уязвимостей анализ нельзя считать глубоким.
По этой же причине нужно анализировать код целиком, а не по частям — иначе можно пропустить межпроцедурные уязвимости.
За последние годы я приобрел большой опыт общения с (потенциальными) заказчиками различных статических анализаторов.
Также мы обсуждаем жалобы на инструменты по результатам первого использования (пилотного).
Большинство претензий так или иначе проистекают из теоретических ограничений технологии.
Кроме того, инструменты могут просто не иметь того функционала, который нужен пользователю.
Однако, на мой взгляд, анализаторы могут (и делают) идти навстречу пользователю в плане решения изложенных ниже задач.
Но нужно еще уметь пользоваться анализаторами, нивелируя последствия этих самых проблем – как оказывается, это не так уж и сложно.
Давайте по порядку.
Можно представить модельную ситуацию: вы решаете опробовать технологию в действии или выбираете статический анализатор и проводите пилот. Конечно, вы не доверяете тестовым примерам производителя и хотите попробовать проанализировать свой код (при этом можно найти реальные уязвимости и исправить их).
Вам предоставляется установщик или готовая виртуальная машина с системой на небольшой срок.
Запуск анализа
Сначала нужно запустить анализ.Заходите в интерфейс, и вроде бы все должно быть понятно: загружаете архив с исходным кодом в форму и нажимаете «анализировать».
Но нет: вы получаете несколько форм с разными полями, которые нужно как-то заполнить.
Вам необходимо указать языки программирования, некоторые настройки анализатора, выбрать пакеты уязвимостей (как узнать, что в них входит?) и так далее.
Вы проходите этот тест и начинается анализ.
О нет, ошибка сканирования.
«Формат не соответствует требованиям», «Для этого языка требуется сборка кода», «Не найдено файлов для сканирования».
Если вы не писали этот код самостоятельно, вам все равно придется обращаться к разработчикам за помощь.
Разработчик отправляет исходный код на тестирование
Требования к сборке кода заслуживают особого внимания.
Большинство анализаторов для ряда языков требуют компиляции кода при анализе (языки JVM — Java, Scala, Kotlin и им подобные, C/C++, Objective-C, C#).
Сами понимаете, какая это боль: воспроизводить окружение большого проекта для сборки на новой машине.
С другой стороны, эти требования оправданы; они вытекают из технологии анализа и специфики этих языков.
Как анализаторы решают эти проблемы? Во-первых, они делают запуск анализа максимально автоматизированным.
В идеале достаточно загрузить файл любого формата, а анализатор сам должен понимать, какие языки есть, как пробовать строить и как выставлять остальные настройки по умолчанию, чтобы результаты были максимально полными.
Понятно, что все предусмотреть невозможно – однако с большинством случаев можно попытаться справиться.
Требования к сборке должны быть максимально гибкими.
Например, для языков JVM нет необходимости требовать ассемблер при анализе — достаточно попросить загрузить артефакты, то есть собранный код вместе с исходным кодом (а это гораздо проще).
Для XCode, в случае Objective-C, сборку в большинстве случаев можно автоматизировать.
Если код не удается собрать, анализатор может попытаться выполнить частичный анализ.
Его результаты не будут такими полными, но это лучше, чем отсутствие результатов вообще.
Также удобно, если модуль анализа можно установить на машину разработчика, где уже настроена сборка кода, при этом архитектура должна позволять переносить остальные модули и интерфейсную часть на другую машину.
Наконец, анализатор должен выдвигать максимально мягкие требования к формату и сам разбираться с входными файлами.
Архив с исходным кодом, вложенные архивы, архив из репозитория, ссылка на репозиторий, архив из продукта, исполняемый файл из продукта — хорошо, если анализатор все это поддерживает. Однако не стоит забывать, что анализатор не обладает искусственным интеллектом и не может всего предсказать.
Поэтому при возникновении ошибок стоит прочитать руководство — там много полезной информации по подготовке кода к анализу.
Ну а вся эта работа по запуску сканирования при реализации анализатора делается только один раз для каждой базы кода.
Чаще всего анализатор вообще интегрируется в цикл CI, то есть проблем со сборкой не будет.
Процесс анализа
Хорошо, сканирование началось.Проходит час - результатов нет. Прогресс-бар висит где-то посередине, непонятно с каким процентом и какой прогноз завершения.
Проходит второй час - прогресс сдвинулся на 99 процентов и висит там уже полчаса.
Проходит третий час и анализатор вылетает, сообщая о нехватке оперативной памяти.
Или висит еще час и заканчивается.
Вы можете ожидать, что анализ будет идти с той же скоростью, что и ваш стиль проверки, и здесь ваши ожидания будут сильно расходиться с реальностью.
Да, хороший статический анализатор может потреблять много ресурсов, одну из причин я указал выше: поиск сложных уязвимостей — задача экспоненциально сложная.
Так что чем больше ресурсов и чем больше времени, тем лучше будут результаты (с хорошим движком, конечно).
И время анализа, и требуемые ресурсы действительно сложно предсказать — время работы алгоритмов статического анализа сильно зависит от языковых конструкций, от сложности кода, от глубины вызовов — от характеристик, которые сложно просчитать заранее.
Проблема ресурсов – это необходимое зло.
Нужно внимательно относиться к выделению необходимых ресурсов, терпеливо ждать завершения сканирования, а также понимать, что никто не может точно предсказать, какие ресурсы понадобятся анализатору, даже при заданной кодовой базе, и нужно быть готовым к изменениям.
эти параметры.
Причем требуемые параметры могут измениться даже без обновления кодовой базы — из-за обновления анализатора.
И все же анализатор может немного помочь с этой проблемой.
Он способен разделить ресурсоемкую часть (движки) и интерфейс на разные машины.
Это позволит вам не нагружать машины ненужными программами, замедляющими их работу, и вы сможете использовать интерфейс системы независимо от загруженности сканирований (например, для просмотра и редактирования результатов).
Это также позволит вам легко масштабироваться без переустановки всей системы (устанавливаем анализатор на новую виртуальную машину, указываем IP основной машины — и вуаля).
Кроме того, анализатор может позволить выбирать глубину анализа, отключать тяжелые проверки и использовать инкрементный анализ (при котором проверяется не весь код, а только измененный).
Этими вещами нужно пользоваться очень осторожно, так как они могут сильно повлиять на результаты сканирования.
Если вы используете этот функционал, рекомендуется через определенные промежутки времени проводить полный анализ.
Результаты анализа
Перейдем к результатам сканирования (мы долго до них добирались).Вы с трепетом ждёте количества уязвимостей в окне анализатора и очень удивляетесь, когда видите это.
156 критических, 1260 средних и 3210 низких.
Вы заходите на страницу результатов и ошеломлены количеством найденных проблем.
Вы скачиваете отчет в формате pdf и видите несколько тысяч страниц текста.
Угадайте, что скажет разработчик кода, когда увидит такое полотно?
Охранник приносит разработчику отчет об уязвимостях
Но давайте все же попробуем увидеть результаты, дадим ему шанс.
Присмотревшись к нескольким десяткам вхождений, начинаешь понимать, почему так много уязвимостей.
Некоторые уязвимости на самом деле выглядят серьезными, и вы знаете, что их необходимо исправить.
Однако вы тут же обнаружите с десяток ложных.
В коде библиотеки также имеется огромное количество уязвимостей.
Вы не будете чинить библиотеки! И тогда понимаешь, сколько времени потратишь на анализ результатов.
И эту процедуру необходимо повторять каждый день, неделю или хотя бы каждый релиз.
(Не совсем).
Начнем с того, что ложные срабатывания можно понимать очень по-разному.
Некоторые люди не будут считать ложными только критические уязвимости, которые можно эксплуатировать прямо сейчас.
Некоторые посчитают ложными только явные ошибки анализатора.
Многое зависит от того, чего вы хотите от инструмента.
Мы рекомендуем учитывать практически все случаи, поскольку даже низкоуровневая уязвимость, которую невозможно эксплуатировать сейчас, завтра может превратиться в серьезную проблему — например, если изменится код и внешние условия.
Ок, нужно просмотреть все записи, но это еще огромный объем работы.
И здесь анализаторы могут очень хорошо помочь.
Важнейшая функция анализатора — возможность отслеживать уязвимости между сканированиями одного и того же проекта, при этом отслеживание устойчиво к небольшим изменениям, стандартным для разработки кода.
Это исключает проблему необходимости повторения длительного анализа уязвимостей: в первый раз вы потратите больше времени на устранение ложных срабатываний и изменение критичности вхождений, а затем вам останется только просмотреть новые уязвимости, которых будет много раз.
меньше.
Хорошо, но нужно ли просматривать все уязвимости с первого раза? Мы рекомендуем это сделать, но, вообще говоря, в этом нет необходимости.
Во-первых, анализаторы позволяют фильтровать результаты по каталогам и файлам: например, при запуске сканирования вы можете сразу исключить из анализа некоторые компоненты, библиотеки или тестовый код. Это также повлияет на скорость анализа.
Во-вторых, анализаторы позволяют фильтровать результаты по уязвимостям, то есть при запуске сканирования можно ограничить набор уязвимостей.
Наконец, помимо критичности, анализатор может выдавать что-то вроде вероятности ложности уязвимости (то есть своей уверенности в данной уязвимости).
Используя эту метрику, вы можете фильтровать результаты.
Отдельно стоит отметить технологию Software Composition Analysis (сейчас все большее количество инструментов начинает поддерживать ее на разных уровнях).
Технология позволяет обнаружить использование библиотек в вашем коде, определить названия и версии, показать известные уязвимости, а также лицензии.
Эта технология позволяет отделять библиотечный код от вашего собственного, что также позволяет фильтровать результаты.
Оказывается, с проблемой обильных результатов анализа можно справиться, и это не очень сложно.
И хотя первый просмотр результатов действительно может занять время, то при повторном сканировании его будет тратиться все меньше и меньше.
Однако еще раз отмечу, что к любой фильтрации результатов следует относиться с осторожностью — вы можете пропустить уязвимость.
Даже если библиотека известна, это не значит, что она не содержит уязвимостей.
Если эта уязвимость на данный момент плохо обнаруживается (то есть инструмент показывает много ложных срабатываний по этой уязвимости), и вы ее отключите, то при обновлении анализатора вы можете пропустить реальную уязвимость.
Проверим анализатор
Имели дело с большим отчетом и ложными срабатываниями.Но вы хотите пойти дальше — убедитесь, что анализатор находит те уязвимости, о существовании которых вы точно знаете (вы могли их установить намеренно, или их нашел другой инструмент).
Для начала важно понимать, что анализатор мог не найти уязвимость по разным причинам.
Самое простое — неправильно настроено сканирование (нужно обращать внимание на сообщения об ошибках).
Но с точки зрения технологии анализа причины могут быть разными.
Статический анализатор состоит из двух важных компонентов: движка (в нем заложена вся алгоритмическая сложность и математика) и базы правил поиска уязвимостей.
Одна из ситуаций — когда движок позволяет найти уязвимость данного класса, но в базе правил уязвимости нет. В этом случае добавить правило обычно не составляет труда.
Совсем другая ситуация, если движок в принципе не поддерживает подобные уязвимости — здесь улучшения могут быть очень существенными.
В начале статьи я привел пример: вы никогда не встретите SQL-инъекцию без алгоритмов анализа потока данных.
Статический анализатор должен реализовать в движке набор алгоритмов, охватывающий доступные классы уязвимостей для данного языка программирования (анализ потока управления, анализ потока данных, интервальный анализ и т. д.).
Важным моментом является возможность добавлять в инструмент свои правила поиска уязвимостей – это устранит первую причину пропуска уязвимости.
Таким образом, если вы не обнаружили в результатах сканирования существующей уязвимости, сначала необходимо понять причину упущения — обычно с этим может помочь вендор.
Если причина в базе правил или конфигурации сканирования, то ситуацию можно решить довольно легко.
Самое главное — оценить глубину анализа, то есть то, что движок позволяет искать.
Компетенции
Прочитав статью до этого момента, можно предположить, что работа с инструментом требует глубокой экспертизы разработчика, ведь нужно понимать, какие позитивы ложные, а какие правдивые.На мой взгляд, все зависит от того, насколько дружелюбный инструмент. Если он предоставляет удобный и понятный функционал, четкие описания уязвимостей с примерами, ссылками и рекомендациями на разных языках, если инструмент показывает следы уязвимостей, связанных с анализом потоков данных, работа с ним не требует глубокой экспертизы разработчика с пониманием все тонкости языка программирования и фреймворков.
Однако для чтения кода все равно необходим минимальный опыт разработки.
Интеграция в процесс разработки
В конце статьи мы кратко коснемся одного из важнейших вопросов использования инструмента и подробно рассмотрим его в следующих статьях.
Допустим, вы решили использовать статический анализатор.
Однако у вас есть налаженный процесс разработки, как технологический, так и организационный, и вы не хотите его менять (и никто не будет).
Инструмент должен иметь полноценный неграфический интерфейс (например, CLI или REST API), с помощью которого вы сможете встроить анализатор в любой ваш процесс.
Хорошо, если у анализатора есть готовые интеграции с различными компонентами: плагины для IDE или систем сборки, интеграция с системами контроля версий, плагины для CI/CD-серверов (Jenkins, TeamCity), интеграция с системами управления проектами (JIRA) или работа с пользователи (Active Directory).
Интеграция статического анализа в процесс разработки (так называемый SDLC) — наиболее эффективный способ его использования, если процесс хорошо налажен и все участники согласны и знают, зачем он нужен.
Постоянный анализ кода после его изменений или обновлений анализатора позволит обнаружить уязвимости как можно раньше.
Разделение ролей разработчиков и специалистов по ИБ, четкое указание требований ИБ и мягкая интеграция в текущий процесс (например, на первых порах – консультативный характер системы) позволят использовать инструмент безболезненно и с пользой.
Однако никто не отменял ручное использование инструмента, если ваша модель разработки не предполагает такого процесса.
Краткое содержание
В статье приведены основные рекомендации по началу использования статического анализатора.Хороший анализатор работает на порядок лучше любого легковесного чекера; он ищет проблемы принципиально иной сложности.
Поэтому нужно учитывать особенности статического анализа как технологии, но при этом выбирать конкретный инструмент так, чтобы его функционал максимально сглаживал все подобные особенности.
Теги: #информационная безопасность #уязвимость #статический анализ кода #sast #SDLC
-
Изучение Разработки Веб-Сайтов Wordpress
19 Oct, 24 -
Литература О Развлечениях, Связанных С Ит
19 Oct, 24