В настоящее время разработано большое количество инструментальных средств, предназначенных для автоматизации поиска уязвимостей программ. В данной статье будут рассмотрены некоторые из них.
Введение
Статический анализ кода — это анализ программного обеспечения, который производится над исходным кодом программ и реализуется без реального исполнения исследуемой программы.
Программное обеспечение часто содержит разнообразные уязвимости из-за ошибок в коде программ. Ошибки, допущенные при разработке программ, в некоторых ситуациях приводят к сбою программы, а следовательно, нарушается нормальная работа программы: при этом часто возникает изменение и порча данных, останов программы или даже системы. Большинство уязвимостей связано с неправильной обработкой данных, получаемых извне, или недостаточно строгой их проверкой.
Для выявления уязвимостей используют различные инструментальные средства, например, статические анализаторы исходного кода программы, обзор которых приведён в данной статье.
Как тестировать сайт? | Уязвимости сайтов | XSS атака | 18+
Классификация уязвимостей защиты
Когда требование корректной работы программы на всех возможных входных данных нарушается, становится возможным появление так называемых уязвимостей защиты (security vulnerability). Уязвимости защиты могут приводить к тому, что одна программа может использоваться для преодоления ограничений защиты всей системы в целом.
Классификация уязвимостей защиты в зависимости от программных ошибок:
- Переполнение буфера (buffer overflow). Эта уязвимость возникает из-за отсутствия контроля за выходом за пределы массива в памяти во время выполнения программы. Когда слишком большой пакет данных переполняет буфер ограниченного размера, содержимое посторонних ячеек памяти перезаписывается, и происходит сбой и аварийный выход из программы. По месту расположения буфера в памяти процесса различают переполнения буфера в стеке (stack buffer overflow), куче (heap buffer overflow) и области статических данных (bss buffer overflow).
- Уязвимости (tainted input vulnerability). Уязвимости могут возникать в случаях, когда вводимые пользователем данные без достаточного контроля передаются интерпретатору некоторого внешнего языка (обычно это язык Unix shell или SQL). В этом случае пользователь может таким образом задать входные данные, что запущенный интерпретатор выполнит совсем не ту команду, которая предполагалась авторами уязвимой программы.
- Ошибки форматных строк (format string vulnerability). Данный тип уязвимостей защиты является подклассом уязвимости . Он возникает из-за недостаточного контроля параметров при использовании функций форматного ввода-вывода printf, fprintf, scanf, и т. д. стандартной библиотеки языка Си. Эти функции принимают в качестве одного из параметров символьную строку, задающую формат ввода или вывода последующих аргументов функции. Если пользователь сам может задать вид форматирования, то эта уязвимость может возникнуть в результате неудачного применения функций форматирования строк.
- Уязвимости как следствие ошибок синхронизации (race conditions). Проблемы, связанные с многозадачностью, приводят к ситуациям, называемым : программа, не рассчитанная на выполнение в многозадачной среде, может считать, что, например, используемые ею при работе файлы не может изменить другая программа. Как следствие, злоумышленник, вовремя подменяющий содержимое этих рабочих файлов, может навязать программе выполнение определенных действий.
Конечно, кроме перечисленных существуют и другие классы уязвимостей защиты.
Где найти уязвимости — как найти уязвимости — поиск информации в интернете
Обзор существующих анализаторов
Для обнаружения уязвимостей защиты в программах применяют следующие инструментальные средства:
- Динамические отладчики. Инструменты, которые позволяют производить отладку программы в процессе её исполнения.
- Статические анализаторы (статические отладчики). Инструменты, которые используют информацию, накопленную в ходе статического анализа программы.
Статические анализаторы указывают на те места в программе, в которых возможно находится ошибка. Эти подозрительные фрагменты кода могут, как содержать ошибку, так и оказаться совершенно безопасными.
В данной статье предложен обзор нескольких существующих статических анализаторов. Рассмотрим подробнее каждый из них.
1. BOON
Инструмент BOON, который на основе глубокого семантического анализа автоматизирует процесс сканирования исходных текстов на Си в поисках уязвимых мест, способных приводить к переполнению буфера. Он выявляет возможные дефекты, предполагая, что некоторые значения являются частью неявного типа с конкретным размером буфера.
2. CQual
CQual — Инструмент анализа для обнаружения ошибок в Си-программах. Программа расширяет язык Си дополнительными определяемыми пользователем спецификаторами типа. Программист комментирует свою программу с соответствующими спецификаторами, и cqual проверяет ошибки. Неправильные аннотации указывают на потенциальные ошибки. Сqual может использоваться, чтобы обнаружить потенциальную уязвимость форматной строки.
3. MOPS
MOPS (MOdel checking Programs for Security) — инструмент для поиска уязвимостей в защите в программах на Си. Его назначение: динамическая корректировка, обеспечивающая соответствие программы на Си статической модели. MOPS использует модель аудита программного обеспечения, которая призвана помочь выяснить, соответствует ли программа набору правил, определенному для создания безопасных программ.
4. ITS4, RATS, PScan, Flawfinder
Для поиска ошибок переполнения буфера и ошибок форматных строк используют следующие статические анализаторы:
- ITS4. Простой инструмент, который статически просматривает исходный Си/Си++-код для обнаружения потенциальных уязвимостей защиты. Он отмечает вызовы потенциально опасных функций, таких, например, как strcpy/memcpy, и выполняет поверхностный семантический анализ, пытаясь оценить, насколько опасен такой код, а так же дает советы по его улучшению.
- RATS. Утилита RATS (Rough Auditing Tool for Security) обрабатывает код, написанный на Си/Си++, а также может обработать еще и скрипты на Perl, PHP и Python. RATS просматривает исходный текст, находя потенциально опасные обращения к функциям. Цель этого инструмента — не окончательно найти ошибки, а обеспечить обоснованные выводы, опираясь на которые специалист сможет вручную выполнять проверку кода. RATS использует сочетание проверок надежности защиты от семантических проверок в ITS4 до глубокого семантического анализа в поисках дефектов, способных привести к переполнению буфера, полученных из MOPS.
- PScan. Сканирует исходные тексты на Си в поисках потенциально некорректного использования функций, аналогичных printf, и выявляет уязвимые места в строках формата.
- Flawfinder. Как и RATS, это статический сканер исходных текстов программ, написанных на Си/Си++. Выполняет поиск функций, которые чаще всего используются некорректно, присваивает им коэффициенты риска (опираясь на такую информацию, как передаваемые параметры) и составляет список потенциально уязвимых мест, упорядочивая их по степени риска.
Все эти инструменты схожи и используют только лексический и простейший синтаксический анализ. Поэтому результаты, выданные этими программами, могут содержать до 100% ложных сообщений.
5. Bunch
Bunch — средство анализа и визуализации программ на Си, которое строит граф зависимостей, помогающий аудитору разобраться в модульной структуре программы.
6. UNO
UNO — простой анализатор исходного кода. Он был разработан для нахождения таких ошибок, как неинициализированные переменные, нулевые указатели и выход за пределы массива. UNO позволяет выполнять несложный анализ потока управления и потоков данных, осуществлять как внутри- так и межпроцедурный анализ, специфицировать свойства пользователя. Но данный инструмент не доработан для анализа реальных приложений, не поддерживает многие стандартные библиотеки и на данном этапе разработки не позволяет анализировать сколь-нибудь серьёзные программы.
7. FlexeLint (PC-Lint)
FlexeLint (PC-Lint) — этот анализатор предназначен для анализа исходного кода с целью выявления ошибок различного типа. Программа производит семантический анализ исходного кода, анализ потоков данных и управления.
В конце работы выдаются сообщения нескольких основных типов:
- Возможен нулевой указатель;
- Проблемы с выделением памяти (например, нет free() после malloc());
- Проблемный поток управления (например, недостижимый код);
- Возможно переполнение буфера, арифметическое переполнение;
- Предупреждения о плохом и потенциально опасном стиле кода.
8. Viva64
Инструмент Viva64, который помогает специалисту отслеживать в исходном коде Си/Си++-программ потенциально опасные фрагменты, связанные с переходом от 32-битных систем к 64-битным. Viva64 встраивается в среду Microsoft Visual Studio 2005/2008, что способствует удобной работе с этим инструментом. Анализатор помогает писать корректный и оптимизированный код для 64-битных систем.
9. Parasoft C++ Test
Parasoft C++ Test — специализированный инструмент для Windows, позволяющий автоматизировать анализ качества кода Си++. Пакет C++Test анализирует проект и генерирует код, предназначенный для проверки содержащихся в проекте компонентов. Пакет C++Test делает очень важную работу по анализу классов C++. После того как проект загружен, необходимо настроить методы тестирования.
Программное обеспечение изучает каждый аргумент метода и возвращает типы соответствующих значений. Для данных простых типов подставляются значения аргументов по умолчанию; можно определить тестовые данные для определенных пользователем типов и классов. Можно переопределить аргументы C++Test, используемые по умолчанию, и выдать значения, полученные в результате тестирования.
Особого внимания заслуживает способность C++Test тестировать незавершенный код. Программное обеспечение генерирует код-заглушку для любого метода и функции, которые еще не существуют. Поддерживается имитация внешних устройств и входных данных, задаваемых пользователем. И та и другая функции допускают возможность повторного тестирования.
После определения тестовых параметров для всех методов пакет C++Test готов к запуску исполняемого кода. Пакет генерирует тестовый код, вызывая для его подготовки компилятор Visual C++. Возможно формирование тестов на уровне метода, класса, файла и проекта.
10. Coverity
Инструменты Coverity используются для выявления и исправления дефектов безопасности и качества в приложениях критического назначения. Технология компании Coverity устраняет барьеры в написании и внедрении сложного ПО посредством автоматизации поиска и устранения критических программных ошибок и недостатков безопасности во время процесса разработки. Инструмент компании Coverity способен с минимальной положительной погрешностью обрабатывать десятки миллионов строк кода, обеспечивая 100-процентное покрытие трассы.
11. KlocWork K7
Продукты компании Klocwork предназначены для автоматизированного статического анализа кода, выявления и предотвращения дефектов программного обеспечения и проблем безопасности. Инструменты этой компании служат для выявления коренных причин недостатков качества и безопасности программного обеспечения, для отслеживания и предотвращения этих недостатков на протяжении всего процесса разработки.
12. Frama-C
Frama-C — открытый, интегрированный набор инструментов для анализа исходного кода на языке Си. Набор включает ACSL (ANSI/ISO C Specification Language) — специальный язык, позволяющий подробно описывать спецификации функций Си, например, указать диапазон допустимых входных значений функции и диапазон нормальных выходных значений.
Этот инструментарий помогает производить такие действия:
- Осуществлять формальную проверку кода;
- Искать потенциальные ошибки исполнения;
- Произвести аудит или рецензирование кода;
- Проводить реверс-инжиниринг кода для улучшения понимания структуры;
- Генерировать формальную документацию.
13. CodeSurfer
CodeSurfer — инструмент анализа программ, который не предназначается непосредственно для поиска ошибок уязвимости защиты. Его основными достоинствами являются:
- Анализ указателей;
- Различные анализы потока данных (использование и определение переменных, зависимость данных, построение графа вызовов);
- Скриптовый язык.
CodeSurfer может быть использован для поиска ошибок в исходном коде, для улучшения понимания исходного кода, и для реинженерии программ. В рамках среды CodeSurfer велась разработка прототипа инструментального средства для обнаружения уязвимостей защиты, однако разработанное инструментальное средство используется только внутри организации разработчиков.
14. FxCop
FXCop предоставляет средства автоматической проверки .NET-сборок на предмет соответствия правилам Microsoft .NET Framework Design Guidelines. Откомпилированный код проверяется с помощью механизмов рефлексии, парсинга MSIL и анализа графа вызовов. В результате FxCop способен обнаружить более 200 недочетов (или ошибок) в следующих областях:
- Архитектура библиотеки;
- Локализация;
- Правила именования;
- Производительность;
- Безопасность.
FxCop предусматривает возможность создания собственных правил с помощью специального SDK. FxCop может работать как в графическом интерфейсе, так и в командной строке.
15. JavaChecker
JavaChecker — это статический анализатор Java програм, основанный на технологии TermWare.
Это средство позволяет выявлять дефекты кода, такие как:
- небрежная обработка исключений (пустые catch-блоки, генерирование исключений общего вида и.т.п.);
- сокрытие имен (например, когда имя члена класса совпадает с именем формального параметра метода);
- нарушения стиля (вы можете задавать стиль программирования с помощью набора регулярных выражений);
- нарушения стандартных контрактов использования (например, когда переопределен метод equals, но не hashCode);
- нарушения синхронизации (например, когда доступ к синхронизированной переменной находится вне synchronized блока).
Набором проверок можно управлять, используя управляющие комментарии.
Вызов JavaChecker можно осуществлять из ANT скрипта.
16. Simian
Simian — анализатор подобия, который ищет повторяющийся синтаксис в нескольких файлах одновременно. Программа понимает синтаксис различных языков программирования, включая C#, T-SQL, JavaScript и Visual BasicR, а также может искать повторяющиеся фрагменты в текстовых файлах. Множество возможностей настройки позволяет точно настраивать правила поиска дублирующегося кода. Например, параметр порога (threshold) определяет, какое количество повторяющихся строк кода считать дубликатом.
Simian — это небольшой инструмент, разработанный для эффективного поиска повторений кода. У него отсутствует графический интерфейс, но его можно запустить из командной строки или обратиться к нему программно. Результаты выводятся в текстовом виде и могут быть представлены в одном из встроенных форматов (например, XML). Хотя скудный интерфейс и ограниченные возможности вывода результатов Simian требуют некоторого обучения, он помогает сохранить целостность и эффективность продукта. Simian подходит для поиска повторяющегося кода как в больших, так и в маленьких проектах.
Повторяющийся код снижает поддерживаемость и обновляемость проекта. Можно использовать Simian для быстрого поиска дублирующихся фрагментов кода во многих файлах одновременно. Поскольку Simian может быть запущен из командной строки, его можно включить в процесс сборки, чтобы получить предупреждения или остановить процесс в случае повторений кода.
Вывод
Итак, в данной статье были рассмотрены статические анализаторы исходного кода, которые являются вспомогательными инструментами программиста. Все инструментальные средства разные и помогают отслеживать самые различные классы уязвимостей защиты в программах. Можно сделать вывод, что статические анализаторы должны быть точными, восприимчивыми. Но, к сожалению, статические средства отладки не могут дать абсолютно надёжный результат.
Библиографический список
- Alexey Kolosov. Using Static Analysis in Program Development
- Брайан Гетц. Избавьтесь от ошибок.
- Криспин Кован. Безопасность систем с открытым кодом.
- Павел Зуев. О компьютерной безопасности.
- С.С. Гайсарян, А.В. Чернов, А.А. Белеванцев, О.Р. Маликов, Д.М. Мельник, А.В. Меньшикова. О некоторых задачах анализа и трансформации программ.
Источник: codenet.ru
Как искать уязвимости в программах
В программах, установленных на вашем компьютере могут быть уязвимости, через которые способны проникнуть вредоносные программы. Проверка вашего компьютера поможет найти эти уязвимости и предотвратить заражение компьютера.
Чтобы запустить поиск уязвимостей, выполните следующие действия:
- Откройте главное окно программы.
- Нажмите на кнопку Больше функций , расположенную в нижней части главного окна. Откроется окно Инструменты .
- Перейдите в раздел Управление программами .
- По ссылке Поиск уязвимостей откройте окно Поиск уязвимостей .
- В окне Поиск уязвимостей нажмите на кнопку Начать поиск .
Kaspersky Internet Security начнет проверку вашего компьютера на наличие уязвимостей.
Начиная с версии Kaspersky Internet Security 2021, из программы был исключен поиск уязвимостей операционной системы. Если вы хотите выполнять поиск уязвимостей операционной системы, вы можете вернуться на предыдущую версию программы.
Источник: support.kaspersky.com
Как искать уязвимости в проекте на Go: обзор популярных анализаторов кода и их возможностей
Привет! Меня зовут Николай Никитас, я бэкенд-разработчик в Авито. В команде я занимаю роль securtity-чемпиона, то есть отвечаю за безопасность проекта.
Чтобы узнать, есть ли в программе уязвимости, мы используем статические анализаторы кода. Это бинарные файлы, которые считывают исходный код программы до сборки и запуска проекта. Так можно найти синтаксические ошибки, потенциальные баги, уязвимые места, бесконечные циклы.
Я расскажу про три статических анализатора, которые заточены под Go: GoSec, Go Vulnerability Manager, GoKart.
Анализатор GoSec
Это популярный и самый старый из актуальных анализаторов безопасности для Go. В его базе 35 уязвимостей, которые встречаются чаще всего. Все опасности, которые они несут, описаны в стандарте CVE.
GoSec CI-интегрирован с платформами Github, Gitlab, Jenkins, Travis CI и другими. Проект поддерживает сообщество разработчиков Go.
GoSec распространяют в формате бинарного файла. Его нужно установить из репозитория Github командой go install
После этого запустить командой gosec ./.
В Авито мы используем GoSec в составе golangci-lint. Проверки запускаются локально у каждого разработчика на этапе предсборки, до деплоя.
Анализатор Go Vulnerability Manager
Go Vulnerability Manager разработала команда Go Security Team. Она развивает язык Go и лучше всех знает о его уязвимостях. В базе анализатора больше 340 уязвимостей, каждая описана в стандартах CVE и CWE.
Go Vulnerability Manager умеет сканировать исходный код и уже собранные бинарные файлы. Он поможет узнать, насколько безопасны чужие программы.
Запускается командой govulncheck ./.
Источники данных Go Vulnerability Manager — международные базы данных уязвимостей NVD и GHSA, open-source-пакеты уязвимостей Go, фиксы безопасности от Go Security.
Данные из всех источников попадают в единую базу Go Vulnerability Manager. Её можно интегрировать через VS Code или запустить бинарный файл сканера командой govulncheck . Также лицензия позволяет без ограничений использовать исходники кода анализатора в своих проектах.
Анализатор GoKart
Наименее известный, но тоже хороший статический анализатор. Его создатели вдохновляются GoSec и хотят сделать ещё лучше. Они используют ту же базу данных из 30+ уязвимостей и похожий принцип работы.
Проектом занимается не только сообщество. Разработку GoKart поддерживает крупная компания Praetorian. Есть надежда, что это поможет ему стабильно развиваться.
Команда для запуска — gokart scan .
Какие уязвимости находит GoSec
Общие уязвимости. В этом коде в комментариях подписаны уязвимые места, которые нашел GoSec:
В третьей строке потенциально серьёзная уязвимость — пакет unsafe. Он позволяет внедрить в достаточно безопасный Go операции, которые работают с памятью напрямую, как в C/C++. Например, взять указатель на небезопасную область памяти и из неё перемещаться в другие области. В этом случае есть вероятность не уследить за границами переменных и получить огромную дыру в безопасности приложения.
В девятой строчке — одна из наиболее неприятных уязвимостей. Это хардкод credential, секретов и паролей. GoSec ищет переменные с названиями вроде password, pswd, login и другим похожим, которые содержат строку. После этого помечает её комментарием, чтобы разработчик обратил на нее внимание.
Но GoSec не умеет искать более сложные ошибки. Например, если пароль возвращает функция.
В 15-й строке — две уязвимости. Первая — попытка слушать 80 порт по TCP/IP 0.0.0.0. Это wildcard-интерфейс — потенциально опасное место, который разработчик скорее всего не планировал оставлять в коде. Вторая — нет обработчика для ошибки, которую вернёт функция net.listen.
Инъекции. GoSec ищет пять разных вариантов, я решил показать два:
// G201 (CWE-89): SQL string formatting (Confidence: HIGH, Severity: MEDIUM) q := fat.Sprintf(«SELECT * FROM foo where name = ‘, os.Args[1]) if _, err := db.Query(q); err t= nil < panic(err) >// G24 (CWE-78): Subprocess launched with a potential tainted input or cmd arguments (Confidence: HIGH, Severity: MEDIUM) if err := syscall.Exec(«rm», []string, nil); err != nil
Первый вариант — это SQL-инъекции. Во второй строке есть попытка вставить в строку значение из аргументов с помощью функции Sprintf() . Здесь не используются параметризированные запросы, а это потенциальная дыра в безопасности базы данных.
Второй вариант — вызов syscall, в котором в качестве аргумента передаётся значение функции. В примере это rm и rf , в которых хранится значение из SQL-запроса. Уязвимость опасная: через инъекцию с использованием syscall можно получить полный доступ к серверу или контейнеру с базой данных.
Уязвимости файловой системы. GoSec находит три вида:
// G306 (CWE-276): Expect WriteFile permissions to be 0600 or less (Confidence: HIGH, Severity: MEDIUM) if err := os.WriteFile(«some.txt», []byte(«some text»), 0777); err != nil < panic(err) >// G303 (CWE-377): File creation in shared tmp directory without using ioutil.Tempfile (Confidence: HIGH, Severity: MEDIUM) if _, err := os.Create(«/usr/tmp/123»); err != nil < panic(err) >file := os.Getenv(«SOME_FILE») // G304 (CWE-22): Potential file inclusion via variable (Confidence: HIGH, Severity: MEDIUM) if _, err := os.ReadFile(«/tmp/» + file + «/blob»); err !=nil
Во второй строке разработчик назначает уровень прав доступа к файлу. Программе нужно только записать данные в файл, но при этом стоит доступ 0777 — для всех пользователей. GoSec предлагает понизить уровень до 0600, то есть разрешить читать и записывать файл только его владельцу.
В седьмой строке пример другой потенциальной уязвимости — предсказуемая директория для временных файлов. В таких файлах может быть много чувствительной информации — например, персональные данные из лога. В Go для создания временных файлов есть специальные функции, которые генерируют непредсказуемый путь. Но если пытаться положить временный файл напрямую в директорию tmp, то возникнет ещё одна дыра в безопасности.
В 14 строке выполняется инъекция в путь для чтения файла, а не в базу. Функция ReadFile() получает в виде аргумента путь, который состоит из конкатенации двух параметров и переменной окружения file. Такая уязвимость позволяет злоумышленнику переопределить переменную окружения и получить доступ к другим файловым директориям.
Уязвимости криптографии. GoSec умеет находить ненадёжные конфигурации TLS и ключи RSA:
// G402 (CWE-295): TLS MinVersion too low. (Confidence: HIGH, Severity: HIGH) cfg c= tls.Config<> // G402 (CWE-295): TLS InsecureSkipVerify set true. (Confidence: HIGH, Severity: HIGH) cfg = tls.Config < InsecureSkipVerify: true, >println(cfg) // G403 (CWE-310): RSA keys should be at least 2048 bits (Confidence: HIGH, Severity: MEDIUM) if _, err := rsa.GenerateKey(bytes.NewReader([]byte<>), 1024); err != nil < panic(err) >// G404 (CWE-338): Use of weak random number gene: (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) println( rand.Int63())
Во второй строчке ошибка в том, что в коде не объявлены минимальная и максимальная версии TLS. Это значит, что программа может использовать минимальную из всех доступных версий — она уже устарела и содержит уязвимости.
В шестой строчке напрямую указано, что нужно сбросить верификацию. GoSec обращает внимание разработчика на это, так как это может быть потенциальной ошибкой.
В 11-й строке задаётся длина ключа RSA. GoSec указывает, что для корректной работы ключа его длина должна быть минимум 2048 бит.
В 17-й строчке используется небезопасная функция-рандомайзер. В Go их две: из пакета математики и криптографическая. В математической функции rand.Int63() применяются предсказуемые алгоритмы, которые легко взломать. Поэтому GoSec проверяет, какой именно рандомайзер указан в конкретном коде и подсказывает, если его нужно заменить.
Устаревшие технологии. GoSec находит четыре устаревших способа хэширования и сетевой пакет с хэшем внутри:
// G501 (CWE-327): Blocklisted import crypto/md5: weak cryptographic primitive (Confidence: HIGH, Severity: MEDIUM) _ = md5.New() // G502 (CWE-327): Blocklisted import crypto/des: weak cryptographic primitive (Confidence: HIGH, Severity: MEDIUM) _, _ = des.NewCipher( []byte<>) // G503 (CWE-327): Blocklisted import crypto/rc4: weak cryptographic primitive(Confidence: HIGH, Severity: MEDIUM) _, _ = rc4.NewCipher([]byte<>) // G504 (CWE-327): Blocklisted import net/http/cgi: Go versions < 1.6.3 are vulnerable to Httpoxy attack: (CVE-2016-5386) (Confidence: HIGH, Severity: MEDIUM) _ = cgi.Serve(http.DefaultServeMux) // G505 (CWE-327): Blocklisted import crypto/shal: weak cryptographic primitive(Confidence: HIGH, Severity: MEDIUM) _ = shal.New()
В этих протоколах для хеширования множество коллизий, поэтому они небезопасные. GoSec указывает, что их лучше не использовать.
Небезопасные ссылки. В Go есть особенность: итератор на каждом шаге цикла перезаписывает сам себя, но при этом не является ссылкой или отдельным значением. GoSec находит небезопасные ссылки на итераторы, которые могут сломать программу.
func bar(s *string) < println(*s) >func main() < // G601 (CWE-118): Implicit memory aliasing in for loop. (Confidence: MEDIUM, Severity: MEDIUM) for _, v := range []string < bar(>
На восьмой строчке разработчик берёт указатель на итератор в цикле, то есть на переменную v. Из-за этого он будет получать не все значения v, а только несколько последних.
Если итераций будет 10 000, то программа выведет 150-200 из них. Так происходит, потому что итератор обновляется быстрее, чем выполняется функция println() .
Результаты проверки на реальных проектах
Я выбрал три проекта, чтобы на их примере показать работу анализаторов кода. Для проверки я запускал анализаторы в два действия: скачивал репозиторий и запускал.
Kubernetes. Весь исходный код проекта есть в открытом доступе. Из трёх анализаторов справился только GoSec, который нашел почти 5000 уязвимостей. Из них 156 — высокого уровня.
Go Vulnerability Manager и GoKart не смогли выполнить анализ, потому что Kubernetes не использует модули go.mod. Я попробовал инициализировать модуль и нашёл пакеты, в которых нет обязательных синтаксических конструкций. То есть, для сборки кроме go build они используют замены исходников и шаблоны.
Docker CE. Старый движок Docker тоже смог проанализировать только GoSec. Он нашел почти 600 уязвимостей, из которых 12 — высокого уровня. Go Vulnerability Manager и GoKart снова не справились.
Мой рабочий проект. Здесь запустились все три анализатора. GoKart при этом не нашел ничего, а Go Vulnerability Manager — две уязвимости в стандартной библиотеке Go. В свежей версии языка эти уязвимости уже поправили.
GoSec выявил девять уязвимостей, из них две были с высоким уровнем. Но на самом деле обе они связаны с переменной password, в которой не были записаны пароли. Семь среднеуровневых уязвимостей — это игнорирование ошибок.
Статические анализаторы кода действительно помогают найти уязвимости. Это показывает пример даже таких крупных проектов, как Kubernetes и Docker CE. При этом использовать анализаторы не сложно, для этого достаточно знать пару команд.
Я не советую воспринимать эти инструменты как гарантию поиска всех уязвимостей, но они точно покажут, где нужно быть внимательнее к коду. Результаты анализа могут быть ложноположительные, как в моём примере с переменной password. Но могут быть и ложноотрицательные, если уязвимость ещё не появилась в базах данных сканеров.
И главное, что нужно помнить: статический анализатор кода не спасёт от ошибок в бизнес-логике или намеренного внедрения бэкдора. В этом случае поможет только качественное ревью кода.
Источник: habr.com