Моделирование угроз для веб-приложения: ревью кода
Модель угроз полезна не как диаграмма для отчёта, а как способ найти опасные допущения в коде: кто может подменить пользователя, обойти проверку доступа или злоупотребить интеграцией. Показываем, как связать угрозы с ревью и рефакторингом.

Начните ревью не с названий уязвимостей
В веб-приложении проверка доступа может стоять в контроллере, бизнес-логике и SQL-запросе — или не стоять нигде. Обычное ревью часто замечает подозрительный код, но пропускает главное: кто управляет входными данными, где меняется доверенная идентичность и на каком шаге пользователь получает доступ к чужому объекту. Моделирование угроз связывает эти вопросы с конкретными границами системы и помогает рефакторить код не наугад.
Что именно моделировать при ревью
У модели должна быть ограниченная цель. Для одного ревью это может быть новый сценарий входа, загрузка документов или API для управления заказами. Не нужно изображать всё приложение до последнего фонового процесса: такая схема быстро устареет и не подскажет, что проверять в pull request.
Сначала зафиксируйте границы и участников. Например: браузер отправляет запрос через API-шлюз в веб-приложение; приложение читает базу данных и обращается к платёжному провайдеру. Отдельно отметьте, где меняется уровень доверия: граница между браузером и сервером, между сервисами, между приложением и внешней системой.
- Активы: учётные записи, персональные данные, документы, деньги, настройки доступа.
- Акторы: анонимный посетитель, вошедший пользователь, администратор, внешний сервис.
- Потоки данных: запросы, токены, файлы, сообщения очереди, ответы интеграций.
- Предположения: например, «клиент присылает только свой идентификатор» или «провайдер всегда возвращает корректный статус».
Именно предположения чаще всего превращаются в дефекты. Если сервер доверяет идентификатору владельца, полученному из тела запроса, пользователь может попытаться подставить чужой. Если приложение верит полю роли из браузера, а не проверяет его по серверной сессии или хранилищу, граница доверия проведена не там.
Три способа превратить модель в вопросы к коду
Универсального метода, который автоматически выдаёт полный список угроз, нет. Для ревью полезно выбрать один основной способ постановки вопросов и не смешивать его с попыткой проверить всё сразу.
| Подход | Что спрашивать | Цена и ограничения |
|---|---|---|
| STRIDE | Можно ли подделать идентичность, изменить данные, отрицать действие, раскрыть сведения, истощить ресурсы или получить лишние права? | Даёт широкий перечень категорий, но сам по себе не ранжирует угрозы. Нужен контекст конкретного потока. |
| Сценарий злоупотребления | Как злоумышленник использует обычную функцию не по назначению: меняет идентификатор заказа, повторяет запрос, загружает неожиданный файл? | Понятен команде и хорошо ложится на тест-кейсы. Можно пропустить угрозы, которые не приходят в голову участникам. |
| Дерево атаки | Какими путями можно достичь цели, например получить чужой документ или изменить платёжные реквизиты? | Помогает разбирать сложные цепочки, но для небольшого изменения может стоить больше, чем принесёт пользы. |
STRIDE — мнемоника для шести классов угроз: подмена, изменение, отказ от действий, раскрытие информации, отказ в обслуживании и повышение привилегий. Она помогает не забыть направление проверки, но не заменяет оценку вероятности и ущерба.
Как вести ревью от сценария к исправлению
Возьмём API, который возвращает документ по его идентификатору. Ревьюер видит запрос вида «получить документ» и задаёт вопрос не только о валидации числа: может ли пользователь запросить документ другого владельца? Проверка должна опираться на полномочия текущего пользователя, а не на то, насколько трудно угадать идентификатор.
- Назовите актив и ущерб. Например, утечка договора раскрывает данные клиента. Проверка: в описании ревью указано, что именно будет скомпрометировано.
- Проследите путь данных. Найдите, откуда приходит идентификатор, где он разбирается и где используется для чтения. Проверка: в ревью можно назвать все точки, через которые запрос достигает хранилища.
- Отметьте границу доверия. Значения из HTTP-запроса контролирует клиент. Проверка: ни одна ветка кода не использует переданные клиентом роль или владельца как доказательство полномочий.
- Сформулируйте угрозу как сценарий. «Пользователь A подставляет идентификатор документа пользователя B и получает содержимое». Проверка: сценарий можно воспроизвести тестом на два аккаунта.
- Проверьте контроль и его обходы. Ищите авторизацию не только в основном обработчике, но и в альтернативных маршрутах, фоновых задачах и кэшировании. Проверка: тест подтверждает отказ для чужого объекта во всех доступных путях.
- Свяжите исправление с тестом. Перенесите проверку полномочий к месту, где приложение загружает объект или принимает решение о доступе. Проверка: позитивный тест разрешает владельцу доступ, негативный — запрещает другому пользователю.
Практичная формулировка замечания звучит так: «Идентификатор документа берётся из запроса, а выборка не ограничена текущим пользователем. Добавьте проверку владения на сервере и тест, где один пользователь запрашивает документ другого». Это лучше, чем «проверьте безопасность» или «возможен IDOR»: автору понятно, где искать проблему и как подтвердить исправление.
Рефакторинг: убирайте опасные допущения, а не просто строки
Небольшой патч может закрыть один маршрут, но оставить соседний с той же ошибкой. Если контроллеры сами собирают запросы и отдельно решают, кому разрешён доступ, правило легко разойдётся. Рефакторинг должен сделать безопасный путь проще и заметнее.
- Сведите проверку доступа к объекту к общему, явно вызываемому месту, а не копируйте условие в каждый обработчик.
- Не принимайте от клиента поля, которые сервер может определить сам: владельца, роль или признак подтверждённой оплаты.
- Разделяйте чтение и изменение прав: пользователь может видеть объект, но не менять его отдельные поля.
- Добавьте тесты на отказ, а не только тест «владелец получает ответ».
- Проверьте, не сохраняют ли кэш, очередь или повторный вызов старое решение о доступе.
Не стоит превращать общий компонент авторизации в магический механизм, который скрыто меняет запросы и не оставляет понятного следа. Для ревью важно быстро увидеть, какое правило действует и на каком объекте. Если новый слой абстракции затрудняет проверку этого ответа, он может увеличить риск вместо того, чтобы снизить его.
Хорошая модель угроз заканчивается не диаграммой, а проверяемым вопросом к коду: кто может сделать это действие над этим объектом — и каким тестом вы докажете отказ всем остальным?
Что ломается и где модель перестаёт помогать
Модель быстро теряет ценность, если описывает систему, которой уже нет. После добавления нового маршрута, интеграции или фонового обработчика прежний список потоков может пропустить новую точку входа. Обновляйте его вместе с изменением, которое пересекает границу доверия, а не раз в год перед аудитом.
Вторая ловушка — считать наличие проверки доказательством защиты. Проверка может выполняться после чтения данных, использовать не тот идентификатор пользователя или обходиться через экспорт и кеш. Третья — оценивать риск только по сложности эксплуатации. Низкая вероятность не делает приемлемой утечку большого объёма чувствительных данных.
Если сценарий касается внешней зависимости, проверьте и её сбои: повторные запросы, задержки, неожиданные ответы. Если затронуты загрузка файлов, лимиты запросов или управление секретами, это отдельные направления модели; не сводите их к проверке авторизации.
Термин. Граница доверия — место, где данные или действия переходят между участниками с разным уровнем контроля. Например, браузер пользователя не считается доверенной средой, даже если запрос пришёл из вашего интерфейса.
Что делать дальше
Возьмите ближайшее изменение, которое добавляет новый маршрут, объект или интеграцию. За 20–30 минут опишите актив, два-три потока данных и одно реалистичное злоупотребление. Затем превратите его в тест и проверьте, что тест падает на старом поведении и проходит после исправления. Время здесь — ориентир для небольшого изменения, а не гарантия полноты анализа.
Для первой проверки выберите сценарий, где цена ошибки понятна: доступ к чужому заказу, изменение роли или повторная отправка операции. Следующий шаг — отслеживать не число заполненных диаграмм, а долю найденных угроз, у которых есть владелец исправления и тест, не дающий дефекту вернуться.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: OWASP Threat Modeling Cheat Sheet, OWASP Application Security Verification Standard
Частые вопросы
Нужно ли моделировать всё приложение перед каждым ревью?
Можно ли использовать только STRIDE?
Сколько времени занимает моделирование угроз?
Нужен ли отдельный инструмент или платная программа?
Как понять, что исправление действительно закрыло угрозу?
Нужно ли повторять моделирование после рефакторинга?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.