Моделирование угроз по STRIDE

Учимся ещё на этапе чертежа находить, где и как систему попытаются сломать — пока это дёшево и пока код ещё не написан.

Моделирование угроз (threat modeling) — структурный разбор архитектуры с вопросом «что здесь может пойти не так с точки зрения злоумышленника» и заранее спланированным ответом на каждую угрозу.

Большинство уязвимостей рождаются не в строчке кода, а в решении на доске: «сюда ходим без авторизации», «этому сервису доверяем», «логи писать не будем». Найти такую проблему в дизайне стоит минуты разговора; найти её же после релиза — это инцидент, ночные дежурства и репутационные потери. Моделирование угроз переносит поиск проблем влево по времени: мы смотрим на будущую систему глазами атакующего до того, как она появилась. STRIDE — самый известный каркас для этого, придуманный в Microsoft, чтобы не полагаться на интуицию «давайте подумаем о безопасности», а идти по списку категорий угроз методично.

Зачем это знать защитнику

Защитник, который умеет моделировать угрозы, перестаёт латать дыры по факту и начинает проектировать так, чтобы дыр было меньше. Это навык архитектора и ревьюера: глядя на схему системы, он называет, какие данные критичны, кто кому доверяет, где проходит граница доверия и какая угроза реальна именно здесь. На code review это превращается в точные вопросы: «а кто проверяет, что этот запрос пришёл от того, за кого себя выдаёт?». Моделировать угрозы законно и полезно для любой своей или клиентской системы — это часть нормального проектирования, а не атака.

Шесть категорий STRIDE

STRIDE — мнемоника по шести типам угроз. Каждой категории соответствует нарушаемое свойство безопасности, и для каждой есть штатный класс защиты.

БукваУгрозаНарушаетЗащита (класс)
SSpoofing — выдать себя за другогоаутентичностьаутентификация
TTampering — подмена данных/кодацелостностьподписи, хеши, валидация
RRepudiation — отрицание действиянеотказуемостьнадёжные журналы, аудит
IInformation disclosure — утечкаконфиденциальностьшифрование, контроль доступа
DDenial of Service — отказ в обслуживаниидоступностьлимиты, квоты, отказоустойчивость
EElevation of privilege — рост прававторизацияпроверки доступа, изоляция

Spoofing

Злоумышленник притворяется другим пользователем, сервисом или машиной: подделанный токен, угнанная сессия, поддельный отправитель письма. Защита — сильная аутентификация: проверяемые токены, MFA, взаимный TLS между сервисами.

Tampering

Изменение данных в пути или в хранилище: правка параметра в запросе, подмена файла, инъекция в БД. Лечится валидацией ввода, контролем целостности (HMAC, подписи) и тем, что сервер никогда не доверяет данным, пришедшим от клиента.

Repudiation

Пользователь совершает действие и потом отрицает его, а доказать нечем, потому что журналов нет или их можно подделать. Ответ — неизменяемый аудит-лог критичных операций с привязкой к субъекту и времени.

Information disclosure

Утечка того, что должно быть скрыто: чужие данные в выдаче, подробная ошибка со стеком, секрет в репозитории. Защита — шифрование при передаче и хранении, минимизация данных и аккуратные сообщения об ошибках.

Denial of Service

Систему лишают доступности: лавина запросов, «тяжёлый» запрос, исчерпание памяти. Помогают rate limiting, квоты, таймауты и проектная отказоустойчивость.

Elevation of privilege

Обычный пользователь получает права администратора через дыру в авторизации. Самая опасная категория — её закрывают строгими проверками доступа на сервере и изоляцией компонентов.

Как это работает под капотом

Метод опирается на модель системы, чаще всего на диаграмму потоков данных (DFD). На ней четыре вида элементов: внешние сущности (пользователь, сторонний API), процессы (ваш сервис), хранилища (БД, файлы) и потоки данных между ними. Поверх рисуют границы доверия — линии, где данные переходят из менее доверенной зоны в более доверенную (например, из браузера в сервер). Дальше для каждого элемента и каждого пересечения границы проходят по буквам STRIDE и задают вопрос «возможна ли здесь такая угроза». Получается список конкретных угроз, привязанных к местам системы, а не абстрактное «надо подумать о безопасности».

Возьмём поток «браузер → API → база». На пересечении границы браузер/сервер сразу всплывает несколько пунктов: для входящего запроса опасно безоговорочно доверять полю роли, потому что это путь к подмене и росту прав.

# УЯЗВИМО: роль берётся из тела запроса, которое контролирует клиент.
# Угрозы STRIDE: Spoofing (подделка отправителя) + Elevation of privilege.
def handle(request):
    user_id = request["user_id"]      # клиент может прислать любой id
    role    = request["role"]         # ... и любую роль
    if role == "admin":
        delete_all_users()           # E: рост привилегий

Здесь видно сразу две буквы: S (сервер верит, что запрос от этого пользователя, без проверки) и E (клиент сам назначает себе роль). Модель угроз просто делает эти буквы явными — и подсказывает, как закрыть каждую.

Как защититься

Идентичность и права берём только из проверенного источника на сервере (валидный токен сессии), а не из тела запроса. Тело запроса — недоверенный ввод по определению.

# БЕЗОПАСНО: личность — из проверенной сессии, права проверяет сервер.
def handle(request, session):
    user = session.authenticated_user   # S закрыт: личность из токена
    if not user.has_permission("delete_users"):  # E закрыт: проверка прав
        raise PermissionError("Недостаточно прав")
    delete_all_users()

В общем виде защитник держит у каждой буквы свой штатный приём: S — аутентификация и MFA; T — валидация и контроль целостности; R — аудит-журналы; I — шифрование и минимизация данных; D — лимиты и отказоустойчивость; E — авторизация на сервере и изоляция. Полезные практики процесса: моделировать угрозы на этапе дизайна и пересматривать при изменении архитектуры; начинать с самых ценных активов; фиксировать решения «угроза → защита → кто отвечает», чтобы они не потерялись; и помнить, что моделирование угроз — это командная работа, а не разовый документ «для галочки».

Итоги

  • Моделирование угроз ищет проблемы в дизайне, где их исправить дёшево, а не в проде, где дорого.
  • STRIDE — шесть категорий: Spoofing, Tampering, Repudiation, Information disclosure, DoS, Elevation of privilege.
  • Каждой букве соответствует нарушаемое свойство и штатный класс защиты.
  • Рабочий инструмент — диаграмма потоков данных с границами доверия; STRIDE проходят по элементам и пересечениям границ.
  • Главный принцип: сервер не доверяет данным от клиента; личность и права берутся из проверенного источника.
Проверьте себя
1. Что обозначает буква «E» в STRIDE и какое свойство безопасности она нарушает?
AEncryption — нарушает доступность
BElevation of privilege — нарушает авторизацию (пользователь получает права выше положенных)
CExposure — нарушает аутентичность
DEavesdropping — нарушает целостность
2. Зачем на диаграмме потоков данных рисуют границы доверия (trust boundaries)?
AЧтобы отметить, где данные переходят из менее доверенной зоны в более доверенную — именно там сосредоточены угрозы и нужны проверки
BЧтобы показать физическое расположение серверов в дата-центре
CЧтобы обозначить, какой код писал какой разработчик
DЧтобы измерить пропускную способность сети между узлами
3. Почему брать роль пользователя из тела входящего HTTP-запроса опасно?
AТело запроса медленно парсится
BТело запроса контролирует клиент, поэтому он может прислать любую роль — это путь к Spoofing и Elevation of privilege; права надо проверять на сервере по проверенной сессии
CРоль в теле запроса занимает слишком много памяти
DHTTP не умеет передавать поле role