Блеск и нищета SAST

Краткая версия доклада:

Набор средств статического тестирования защищенности приложений (Static Application Security Testing, SAST) используется для анализа приложений на уязвимость в статичном состоянии, т.е. без выполнения самого приложения. Функционирование SAST проходит в четыре этапа: статический анализ исходного кода приложения, исследование конфигурации на предмет безопасности, проверка зависимостей и поиск секретов (секретные данные, оставленные разработчиками в репозитории).

Статическое тестирование проводится на CI системах. Как правило, результаты сохраняются в хранилище данных, и дальше часть информации отображается на дашбордах, которые могут видеть разработчики и команда безопасности, а часть – отправляется в project tracker, через который разработчики получают тикеты о наличии уязвимости приложения и необходимости ее устранения. Также автоматически создаются уведомления о проблемах с компонентами от третьей стороны или секретами.

С помощью статического анализа в Яндексе решаются такие специфические проблемы, как поиск секретов или анализ зависимости на уязвимости. Кроме того, существуют платформы, на которых динамический анализ (DAST) не работает в полном объёме, как в случае с Windows. В целом можно сказать, что при отсутствии мощной инфраструктуры для динамического тестирования гораздо эффективнее использовать SAST, равно как и при проверке единичных случаев нарушения безопасности. В Яндексе используется несколько статических анализаторов кода – Clang Static Analyzer и Coverity для C/C+, Findbugs и Find security bugs для Java, Coverity для JavaScript, Bandit для Python.

Статический анализ используется для различных целей. В частности, при анализе веб-приложений выявляются места и компоненты, пытающиеся заниматься парсингом небезопасных форматов данных (XML или YAML), выявляется небезопасное использование различных API и других платформ (например, небезопасного генератора случайных чисел), SQL-инъекции, а также неверное кодирование или экранирование выводимых данных. Что касается бинарных приложений, то SAST применяется для анализа ситуаций неправильной работы в разных потоках («гонках»), а также при ошибках и порче памяти.

Стоит отметить, что в ряде случаев установленные анализаторы работают некорректно. Например, Bandit указывает на опасность использования модуля Pickle в Python, что неверно в случае использования доверенных библиотек. В случае с Coverity, анализатор может найти уязвимость DOM Based XSS в коде, несмотря на наличие надежного кастомного экранирования данных. В целом можно сказать, что использование SAST чревато большим количеством таких срабатываний.

За месяц использования каждый анализатор обнаружил менее 10 уязвимостей высокого уровня опасности и не более 30 – среднего уровня (безусловный лидер здесь – Coverity). Что касается ошибочных срабатываний, то в Яндексе провели большую работу по тюнингу анализаторов и снижению уровня их «шума», в том числе путем отключения распознавания уязвимостей с низким уровнем угрозы. Coverity и в этом случае выступает лидером – около 30 полезных срабатываний против 10 ошибочных. У Bandit и Find security bugs соотношение ниже, примерно 50 на 50, однако следует иметь в виду, что при отсутствии наладки и установке анализаторов «как есть», из коробки, процент ложных срабатываний может дойти до 80%.

Исходя из опыта использования, можно сказать, что SAST подходит в первую очередь для обработки потенциально опасных форматов данных, когда используются известные стандартные библиотеки, с которыми умеют работать анализаторы. Также они хорошо справляются с вызовом API небезопасным способом, например, при использовании небезопасного генератора случайных чисел, отдачей shell-команды, при включенном debug режиме и т.п. Анализатор также хорошо находит стандартную SQL-инъекцию. Во всех этих случаях эффективность SAST выше 70%. Говоря о бинарных системах, можно отметить, что хорошо работает только поиск неинициализированных переменных и всяких членов класса.

Средние показатели анализаторы демонстрируют в поиске некорректного эскейпинга – здесь результат от 50% до 70%, причем в нестандартных случаях показатель ещё ниже. Очень плохо работает поиск проблем с памятью в C++ приложениях – тут точность менее 20%, так как анализаторы не понимают семантики умных указателей. Плохо находятся проблемы с утечками данных, не всегда раскручивают макросы, которые могут быть в коде, довольно часто размеры объектов вычисляются неверно, не всегда учитывается архитектура.

Основываясь на полученном опыте, мы рекомендуем при внедрении SAST проанализировать проект и выбрать релевантный код, исключить тесты и third-party компоненты. Также необходимо следить за правилами, которые встроены в SAST-анализаторы и отключать те из них, которые работают некорректно. Полученные результаты анализа мы рекомендуем разделить на две части – для разработчиков и для security-команды для того, чтобы разработчики видели только более-менее точный результат.

Отметим, что ряд статических анализаторов кода (Bandit, FindSecBugs) базируются на регулярных выражениях и зачастую SAST не может объяснить, какие данные идут от пользователя, а какие – нет. Coverity пытается это делать, но у неё это получается не очень хорошо. В целом можно сказать, что SAST неплох при поиске стандартных уязвимостей, однако для более сложных случаев необходимо использовать динамический анализ.