Comments 17
В смысле, разработчику ведь для понимания тоже придётся прослеживать все пути — значит, надо где-то их разорвать, воткнув по дороге какой-то контракт. Чтобы статическому анализатору достаточно было проверить выполнение контракта, а не весь путь.
Что касается «просто проверять выполнение контракта» — вы меня не поняли. Идея в том, что если контракт написан — нужно проверить, выполняет ли его одна сторона, и если да — проверка для второй резко упрощается, достаточно просмотреть лишь пути для выполненного контракта. И это не ослабляет проверку, а ужесточает её: мы проверим и общую корректность, и выполнение контракта.
- Что вы делаете с критическими уязвимостями в библиотеках?
Казалось бы, шансов на то, что злоумышленник тоже проанализировал библиотеку и массово ищет ее уязвимости в вашем проекте (вариант — по всем сайтам в интернете) намного больше, чем на поиск уникальных уязвимостей. Выходит, одна такая оставленная уязвимость практически множит на ноль все остальные усилия по повышению безопасности? - Какие анализаторы из тех, что вы использовали в своей практике можете посоветовать как максимально простые во внедрении?
Для всех технологий, где вам удалось внедрить анализатор в не академический проект и не выкинуть его в течение пары-тройки месяцев.
Оценка опасности уязвимости. Если не опасная, то можно проигнорировать (но так лучше не делать). Если опасная, то либо обновлять библиотеку (если там уже поправили), либо патчить зависимость самим ( и желательно патч в апстрим заслать).
Зависит от используемой Вами технологии.
Зависит от используемой Вами технологии.
Ну, меня много технологий интересует :)
.NET
.NET Core
Ruby on Rails
Elixir
Android — Java & Kotlin
JavaScript (Node.js, React, React Native)
C/C++ — Windows, Linux
Я сам пытался несколько раз, но всегда застревал на этапе «я уже 3 дня этим занимаюсь, а исправил/внимательно посмотрел только 10-15% от общего объема, из просмотренного половину исправить не могу, а заказчик требует новых фич».
Собственно, просьба поделиться опытом именно практического внедрения, у кого оно состоялось хоть куда-нибудь. Без общих слов, только хардкор — анализатор, технология, размер проекта в Мб/KLoc, время внедрения в вашем случае в человеко-месяцах, как долго использовалась (используется).
Это позволяет внедрить анализатор в проект любого размера и получать пользу от этого на следующий же день. Ни в коем случае не надо править сразу все сообщения, которые выдаст анализатор при первом запуске на реальном большом проекте. Исправление сотен или даже тысяч сообщений почти наверняка приведет к появлению новых проблем.
Их надо править постепенно, планово выделяя на это время.
Вам хочется цифр и конкретики. ОК, я лично участвовал во внедрении анализатора в C++ проект размером 8 млн строк кода. При первом запуске там было порядка 5 000 сообщений от анализатора уровней High и Medium («совсем страшно» и «страшновато»). Сообщения уровня Low («скорее всего не ошибка, но мало ли») игнорировались и не правились. Полный прогон такого проекта в PVS-Studio занимал 6 часов.
Все 5 000 ошибок были сначала подавлены как «неинтересные», и разработчики смогли получать уведомления только о новых ошибках. И сразу их править. На эти оставшиеся 5 000 ошибок была выделена команда 3-5 человек, которая победила их за 3-4 месяца. Цифры немного плавающие, так как кроме этого были все же и другие задачи с разной интенсивностью для этой команды, но в целом порядок оценить можно довольно точно.
Внедрения очень разные, от ручного использования раз в месяц до интеграции в CI.
Из первого: мобильные приложения iOS и Android (два приложения, средние по размеру), заказчик примерно раз в месяц сканирует приложение по ссылке на Google Play и AppStore, ранжирует уязвимости, используя функционал инструмента, передает разработчикам уже финальный отчет для исправления.
Из второго: Java, 4.5 млн LOC, запуск из Jenkins раз в сутки. Внедрение шло 2 месяца, но в основном это связано с тем, что нужно было наладить организационный процесс (взаимодействие подразделений по использованию инструмента).
Думаю, мы напишем отдельную статью про опыт внедрения.
Оценить время внедрения сложно. У нас парочка «волонтеров» настроили билды для всей фирмы, прогоняется раз в неделю. Для самого большого моего проекта (1 млн LOC) анализ занимает 1 час (в самом начале занимал около 8 часов, я не знаю что и как оптимизировали).
Мои затраты были наверное около пары недель чистого времени. В самом начале надо разобраться, понять в чём суть уязвимостей, как их чинить. Потом разгребается всё весьма быстро, много однотипных вещей, которые можно одной строчкой поправить или вообще отклонить.
Что важно — четкая позиция менеджмента «к такой дате ни одного critical или high». Тогда это работает. Уже пару проектов почистил полностью, еще немного осталось. Опять таки у нас регулярно проходит аудит безопасности, и пен-тестеры временами находили дырки, уже найденные Fortify — сильно мотивирует.
Medium и Low больше похожи на «плохие практики» чем реальные проблемы, так что просматриваю но не стремлюсь закрывать.
Весьма важна интеграция с багтрекером. Очевидно, что практически везде можно создавать баги, но Fortify умеет их закрывать или переоткрывать по результатам следующего прогона.
Ещё важна поддержка от вендора. У нас вообще есть отдельный проект на котором пробуем разные «ошибки», удобно сразу постить баги. Этакий юнит тест для анализатора :) за последний год они поправили очень много ошибок, ушло очень много false positive. Хотя до сих пор ловит все null propagation (?.) как Possible Null Reference.
Изначально тестировали анализ по команде из Студии (gradle-task), когда обкатали, встроили в основной процесс — анализ происходит на этапе сборки приложений в TeamCity.
Сборку реально пока не блокирует, только алармит всем заинтересованным о найденных проблемах.
Когда вычистим весь код, сделаем негативный результат анализа блокирующим для продолжения сборки.
Ориентировочные объемы:
30 проектов, суммарно 203 тыс. строк кода.
Разным анализаторам нужно разное. Кто-то работает на исходном коде (или, например, на AST, который сам же строит по исходному коду), а кому-то «достаточно» бинарника (в кавычках, потому что это не обязательно меньшее требование — как описано в статье, собрать исходники может быть не так тривиально). Это может быть или совсем «нативный» бинарник (например, для C/C++), или набор class-файлов для Java/Kotlin/Scala — и class-файлы, кстати, во многом сохраняют семантику исходного кода, в большей степени, чем «совсем бинарники».
С бинарниками ещё возникает сложность с тем, чтобы найденную уязвимость пользователю отобразить — нельзя же написать, что «в библиотеке Foo есть SQL-инъекция». Более крутые анализаторы способны декомпилировать бинарник и сопоставить место, где нашли в нём уязвимость, строчке в декомпилированном коде.
А если они с исходным кодом, то что мешает их исправлять?
Может быть, их исходный код и доступен (в публичном репозитории), но чтобы внести туда свои правки, нужно делать форк, pull request, ждать следующего релиза и т.д. Альтернативно, можно, конечно, собирать проект со своей копией библиотеки, а не пытаться исправить уязвимость в upstream'е, но это много другой головной боли.
Про это мы немного писали в блоге, например про байткод Java и анализа iOS-приложений (раз и два).
Отсутствие инъекций вполне можно доказать системой типов. На уровне типов можно различать пришедшие снаружи строки и строки, прошедшие обработку, необходимую для помещения в запрос. Или можно генерировать запросы с помощью DSL (LINQ, Slick).
Да, можно и нужно использовать систему типов для таких вещей. Проблема в том, что это решение принимает разработчик библиотеки для работы с БД, а не автор конченой программы (и тем более не анализатор). И в случае JDBC, например, запросы передаются в виде String sql
.
Так что конечно было бы лучше, если бы все использовали систему типов, но анализатор всё равно должен уметь находить SQL-инъекции в коде, который использует «сырые» строки.
Как правильно использовать статический анализ