Управление уязвимостями отвечает на вопрос, что происходит с находкой после того, как её нашли. Аудит, сканер или проверка кода дают список, а процесс превращает список в закрытые дыры: у каждой находки есть запись, приоритет, ответственный, срок и проверка, что исправление работает. Без процесса отчёт об аудите лежит в почте, а через полгода те же ошибки находят снова.
Процесс не требует дорогих систем: для команды из нескольких разработчиков хватает таблицы или трекера задач и недельной договорённости. Как проводится сама проверка, описано на страницах «Аудит безопасности веб-приложения» и «Secure code review», как встроить автоматические проверки в сборку — на странице «Внедрение DevSecOps». Здесь о том, что делать с их результатами.
Шесть шагов: от находки до закрытия
Весь процесс помещается в шесть шагов. Если какой-то пропущен, находки накапливаются или закрываются «на словах».
| Шаг | Что происходит | Что на выходе | Кто отвечает |
|---|---|---|---|
| 1. Найти | Аудит, ревью кода, проверка в сборке, сообщение пользователя или сторонней организации | Сырая находка с описанием места | Источник находки |
| 2. Записать | Находка заносится в реестр, дубли склеиваются, ложные срабатывания помечаются с причиной | Запись с номером и статусом | Ответственный за безопасность в команде |
| 3. Оценить | Определяется серьёзность, достижимость и ценность данных, которые лежат за ошибкой | Приоритет | Тот, кто знает приложение: техлид и ответственный за безопасность |
| 4. Назначить | Ставится владелец и срок по приоритету, создаётся задача | Задача в трекере со сроком | Руководитель разработки |
| 5. Исправить | Правка кода, обновление зависимости или смена настройки; если сразу нельзя, временная мера | Изменение, прошедшее обычное ревью | Владелец задачи |
| 6. Проверить | Повторная проверка тем же способом, которым нашли, и тест на регрессию | Статус «закрыто» с подтверждением | Не исполнитель, а второй человек или автоматика |
Шаги 2 и 6 пропускают чаще всего. Без записи находка живёт в чьей-то голове, без проверки закрытие означает «разработчик сказал, что исправил».
Откуда берутся находки и сколько в них шума
Источников несколько, и у каждого свой характер. Один даёт мало находок, но точных, другой много, и половина из них не требует действий.
| Источник | Что даёт | Шум | Кто разбирает |
|---|---|---|---|
| Аудит или ревью кода человеком | Ошибки логики и прав, которые автоматика не видит | Мало: каждая находка с воспроизведением | Автор отчёта вместе с вашим разработчиком |
| Статический анализ кода в сборке | Опасные конструкции: сборка запросов строкой, слабая криптография, секреты в коде | Заметный: часть срабатываний относится к недостижимому коду | Разработчик в рамках ревью изменения |
| Проверка зависимостей | Известные уязвимости в используемых библиотеках | Высокий: уязвимая функция может не вызываться у вас | Ответственный за безопасность, раз в неделю |
| Динамическая проверка стенда | Проблемы настройки и заголовков, видимые снаружи | Средний: нужен разбор на стенде | Ответственный за безопасность |
| Сообщение пользователя или исследователя | Находки, которые вы пропустили | Разный; требуют быстрой реакции | Руководитель разработки, тот же день |
| Инцидент | Подтверждённая эксплуатация ошибки | Нет, это факт | Руководитель с участием владельца системы |
| Опросник клиента | Вопросы, на которые нечем ответить | Мало, но это сигнал о слепых зонах | Ответственный за безопасность |
Разницу между статическим анализом, динамической проверкой и анализом зависимостей подробно описывает статья «SAST, DAST, SCA: в чём разница», а настройку в вашей сборке — страница про анализ кода и зависимостей. Для процесса важно одно: все источники сходятся в один реестр, иначе приоритеты сравнивать не с чем.
Реестр: что записывать по каждой находке
Реестр — это таблица или проект в трекере задач. Он нужен не контролёру, а вам: через три месяца по нему видно, что открыто, что закрыто и почему. Минимальный набор полей:
- Номер и краткое название. «Доступ к чужим заказам по номеру в адресе», а не «IDOR».
- Место. Адрес, файл и функция либо библиотека и версия.
- Как воспроизвести. Шаги, по которым разработчик увидит проблему сам. Находка без воспроизведения плохо проверяется при закрытии.
- Источник и дата. Кто нашёл и когда. По дате считается возраст находки.
- Серьёзность, достижимость, ценность данных. Три отдельные отметки, а не одна общая.
- Владелец и срок. Фамилия человека, а не название команды.
- Статус. Новая, подтверждена, в работе, исправлена, проверена, закрыта, ложная, принят риск.
- Ссылка на исправление и на проверку. Изменение в репозитории и тест либо запись о повторной проверке.
Не копируйте в реестр секреты и данные клиентов, найденные при проверке: достаточно описания места. Сам реестр содержит сведения об уязвимостях, поэтому доступ к нему узкий.
Как расставлять приоритеты: три вопроса вместо одной оценки
Единая оценка серьёзности из сканера или из каталога уязвимостей описывает ошибку в вакууме. Для вас важнее три вопроса, и ответы на них меняют порядок работ.
- Насколько опасна сама ошибка? Чтение чужих данных, выполнение чужого кода и обход входа опаснее, чем отсутствие заголовка.
- Достижима ли она? Виден ли уязвимый адрес снаружи, нужна ли учётная запись, вызывается ли уязвимая функция библиотеки в вашем коде.
- Что лежит за ней? Персональные данные, деньги, учётные записи администраторов или справочник городов.
Ниже условные примеры, показывающие, как одни и те же вопросы дают разный порядок.
| Условная находка | Опасность | Достижимость | Что за ней | Решение |
|---|---|---|---|---|
| Клиент открывает заказы другого клиента, меняя номер в адресе | Высокая: чтение чужих данных | Любой вошедший пользователь | Контакты и суммы заказов | Первая очередь, исправить сразу |
| Библиотека с уязвимостью, функция не вызывается | Высокая по описанию | Низкая: код не используется | Не применимо | Обновить в плановом порядке, не срочно |
| Ключ доступа к базе найден в истории репозитория | Высокая | Зависит от доступа к репозиторию | Вся база | Заменить ключ в тот же день; историю чистить потом |
| Администратор входит без второго фактора | Средняя | Только из внутренней сети | Права на все данные | В ближайший релиз, с временной мерой на сети |
| Не хватает одного защитного заголовка | Низкая | Требует другой уязвимости | Публичные страницы | По плану, вместе с другими настройками |
Видно, что высокая серьёзность по описанию не значит срочность, а средняя может оказаться срочной. Принимать такие решения лучше вдвоём: тот, кто знает приложение, и тот, кто знает ошибки.
Сроки и владельцы: как не превратить реестр в кладбище
Срок задаётся классом приоритета, а не настроением недели. Ниже шкала в качестве отправной точки; значения подстройте под ваш ритм релизов и запишите в регламент. Сроки считаются от подтверждения находки.
| Класс | Реакция | Срок исправления | Если не успеваем |
|---|---|---|---|
| Критический: эксплуатация идёт или тривиальна, под угрозой данные клиентов | В тот же день | В течение нескольких дней, вне обычного релиза | Временная мера немедленно: закрыть функцию, отключить доступ, сменить ключи |
| Высокий | В течение рабочего дня | Ближайший релиз, обычно в пределах недели-двух | Временная мера и письменное решение руководителя |
| Средний | В течение недели | Ближайшие один-два релиза | Перенос с новой датой и указанием причины |
| Низкий | При разборе очереди | По плану, вместе с другими работами | Закрыть как «принят риск» или удалить из реестра с пояснением |
Три правила делают шкалу рабочей:
- У срока есть владелец-человек. Задача, у которой записано «команда разработки», не имеет исполнителя.
- Просрочка видна. На недельном разборе первым делом смотрят то, что вышло за срок, а не новые находки.
- Нельзя молча сдвинуть срок. Перенос оформляется записью: новая дата и причина. Три переноса подряд означают, что нужно либо выделить время, либо пересмотреть класс.
Когда находка считается закрытой, и как принимать риск письменно
«Исправлено» и «закрыто» — разные статусы. Закрыто то, что проверено вторым человеком или автоматикой.
- Исправление прошло обычное ревью и попало в релиз, который работает у пользователей, а не только в ветке.
- Для логической ошибки добавлен тест, который падает на старом коде: тогда ошибка не вернётся незаметно.
- Тем же способом, которым находку нашли, проверено, что она больше не воспроизводится: тот же прогон, тот же запрос, повторное срабатывание сканера.
- Временные меры, поставленные на время исправления, сняты или записаны как постоянные.
Исключения: принятие риска
Иногда исправлять нецелесообразно: ошибка в устаревшем модуле, который выведут из эксплуатации, или исправление дороже возможного ущерба. Это допустимо, если решение оформлено, а не забыто:
- Кто принял. Руководитель, у которого есть право отвечать за последствия, а не автор кода.
- Почему. Одна-две фразы с описанием, что именно остаётся открытым.
- Чем компенсируем. Ограничение доступа по сети, усиленный журнал, оповещение о попытках.
- Когда пересмотрим. Дата в календаре. Исключение без даты превращается в бессрочное.
Метрики и ритм: что смотреть, чтобы процесс не умер
Хватает четырёх показателей, их можно считать вручную из реестра. Они показывают состояние процесса, а не количество найденных ошибок: рост числа находок после включения проверок означает, что вы стали видеть больше, а не что стало хуже.
- Возраст открытых находок. Самая старая критическая и самая старая высокая. Это главный показатель: он показывает, где процесс застрял.
- Просроченные. Сколько находок вышло за срок и у кого. Растущий список говорит, что не хватает времени, а не людей.
- Повторные. Сколько находок возвращается после закрытия. Они показывают, что закрывали симптом, а не причину, и что нет тестов.
- Время реакции на критические. От сообщения до первой меры.
Ритм простой. Раз в неделю короткий разбор: просроченное, новое, решения по приоритетам. Раз в квартал полный просмотр реестра: исключения с наступившей датой, находки без движения, ложные срабатывания. После крупного релиза или смены подрядчика добавляется внеочередной разбор. Для небольшой команды это полчаса в неделю, а не отдельная должность. Если проверки в сборке только внедряются, ориентиром служит статья «DevSecOps: с чего начать небольшой команде».
Признаки того, что процесс не работает
Процесс ломается тихо. По этим признакам понятно, что пора что-то менять:
| Признак | Что за ним | Что делаем |
|---|---|---|
| Отчёт аудита лежит в почте, реестра нет | Находки не получили владельцев | Заводим реестр и переносим находки с приоритетами и сроками |
| Все находки названы срочными | Приоритеты не различаются, срочным нельзя заниматься | Вводим три вопроса и классы; критических остаётся единицы |
| Закрывает тот же, кто исправлял | Нет независимой проверки | Закрывает второй человек или повторный прогон |
| Сканер выдаёт сотни срабатываний, никто не смотрит | Шум победил сигнал | Отключаем правила, не применимые к вам, разбираем остальное по приоритетам |
| Сроки переносят без записи | Срок ничего не значит | Любой перенос с причиной и датой, три переноса пересматривают класс |
| Исключения без даты пересмотра | Риск принят навсегда без решения об этом | Всем исключениям ставим дату и владельца |
| Исправили, а через релиз то же самое | Нет теста на регрессию | Добавляем тест к каждому исправлению логической ошибки |
Что делаем мы и с чего начать
Начинаем с обследования: 200 000 ₽ за один-два процесса и 2–3 недели, 350 000 ₽ и 3–4 недели, если приложений несколько. Если нужны находки, проводим аудит безопасности или ревью кода: отчёт содержит воспроизведение, серьёзность и порядок исправления, то есть записи, готовые для реестра. Мы помогаем завести реестр, согласовать классы и сроки, настроить проверки в сборке и разобрать первые срабатывания. Исправление найденного оценивается отдельно, от 150 000 ₽, и заказывать его у нас не обязательно. Стоимость обследования вычитается из первого этапа, если продолжаете с нами.
Мы не берём на себя круглосуточное дежурство и реакцию на инциденты в течение часа, не поставляем системы мониторинга безопасности, не проводим пентест боевых систем и аттестацию, лицензии ФСТЭК у нас нет. Исходный код и реестр остаются у вас с первого дня. Цены и сроки — на странице «Тарифы». Как проходит проверка кода — на странице «Secure code review», как встроить безопасность в весь цикл разработки — на странице «Безопасная разработка веб-приложений».
Частые вопросы
Чем управление уязвимостями отличается от аудита?
Аудит — разовая проверка, которая даёт список находок. Управление уязвимостями — постоянный процесс, который доводит находки до закрытия: запись, приоритет, владелец, срок, проверка. Аудит можно заказать один раз, процесс живёт в вашей команде.
Нужна ли для этого специальная система?
Для небольшой команды нет. Хватает таблицы или проекта в трекере задач с полями из статьи и недельного разбора. Специализированные системы нужны, когда находок много и источников больше пяти, но заводить процесс стоит с таблицы.
Как выбрать приоритет, если сканер ставит всем высокую серьёзность?
Задать три вопроса: насколько опасна ошибка, достижима ли она у вас и что лежит за ней. Оценка сканера описывает ошибку в вакууме. Уязвимая функция библиотеки, которая не вызывается в вашем коде, срочной не бывает, а ошибка прав с доступом к клиентам срочна даже при средней оценке.
Какие сроки исправления разумны?
Критические исправляют в течение нескольких дней, вне обычного релиза, с временной мерой в тот же день. Высокие уходят в ближайший релиз, средние в ближайшие один-два релиза, низкие по плану. Это отправная точка, значения подстраивают под ритм релизов и записывают в регламент.
Что делать, если исправить нельзя или слишком дорого?
Принять риск письменно: кто принял, почему, чем компенсируем и когда пересмотрим. Решение принимает руководитель, а не автор кода, и у исключения всегда есть дата пересмотра. Без неё исключение превращается в бессрочное.
Как понять, что находка действительно закрыта?
Если исправление проверено вторым человеком или автоматикой тем же способом, которым находку нашли, и есть тест, который падает на старом коде. Слова разработчика «исправил» закрытием не считаются.
Сколько времени это занимает у команды?
Для небольшой команды около получаса в неделю на разбор и время на сами исправления. Дольше всего занимает запуск: завести реестр, согласовать классы и сроки, разобрать накопившиеся находки.
Сколько стоит помощь с запуском процесса?
Обследование стоит 200 000 ₽ за 2–3 недели (350 000 ₽ за 3–4 недели при нескольких приложениях) и вычитается из первого этапа, если продолжаете с нами. Аудит безопасности или ревью кода оцениваются по той же шкале. Исправление найденного — от 150 000 ₽, сопровождение — 20 000, 60 000 или 120 000 ₽ в месяц.