Расскажите про опыт устранения уязвимостей в проекте
Что проверяют
Отличаете ли вы «прогнали сканер и обновили зависимости» от разбора конкретной уязвимости: где нашли, почему она работала, что изменили и как убедились, что закрыли. Для Go дополнительно смотрят знание стандартной библиотеки, потому что заметная часть дыр закрывается выбором правильного пакета, а не своей защитой.
Как отвечать
Возьмите один случай и пройдите по шагам: как обнаружили (отчёт сканера, пентест, инцидент, ревью), в чём была причина, чем закрыли, чем проверили. Типичные для Go сюжеты:
- SQL-инъекция: запрос собирали через
fmt.Sprintf, заменили на плейсхолдеры и аргументыdatabase/sql; - межсайтовый скриптинг: страницу рендерили через
text/template, который ничего не экранирует. Лечится переходом наhtml/templateс контекстным экранированием; - предсказуемые токены: идентификаторы сессий брали из
math/rand, заменили наcrypto/rand; - отказ в обслуживании: у сервера не выставлены таймауты чтения и записи, тело запроса читается целиком без ограничения. Помогают таймауты и
http.MaxBytesReader; - уязвимые зависимости:
govulncheckпроверяет не только версию модуля, но и достижимость уязвимой функции из вашего кода, поэтому ложного шума меньше.
Закончите тем, что осталось в процессе: статический анализ gosec и проверка зависимостей в пайплайне, прогон тестов с флагом -race, регулярное обновление модулей.
Где спотыкаются
Рассказывают про ручное экранирование строк вместо правильного шаблонизатора. Своя функция очистки всегда неполная, а контекстное экранирование учитывает, куда именно подставляется значение.
Говорят «нашли и закрыли все уязвимости, аудит прошли без замечаний», не называя ни одного класса. Такой ответ не отличить от пересказа чужого отчёта.
Путают проверку входных данных и экранирование вывода. Одна и та же строка безопасна в теле JSON и опасна в атрибуте HTML, поэтому экранировать нужно в точке вывода, а валидация решает другую задачу.