Требования безопасности и abuse cases
Учимся записывать требования безопасности так же чётко, как функциональные, и заранее описывать, как функцию попытаются употребить во зло.
Abuse case (кейс злоупотребления) — сценарий намеренно враждебного использования функции: что сделает не добросовестный пользователь, а злоумышленник, и как система должна на это ответить.
Команды охотно пишут, что система должна делать: «пользователь загружает аватар», «менеджер видит отчёт». Гораздо реже фиксируют, чего она делать не должна: «нельзя загрузить исполняемый файл вместо картинки», «нельзя увидеть чужой отчёт по подобранному id». Эти «не должна» — и есть требования безопасности и кейсы злоупотребления. Если их не записать, они не попадут в реализацию, не попадут в тесты и всплывут уже как уязвимость. Цель урока — научиться вытаскивать такие требования из обычных функциональных и доводить их до «готово».
Зачем это знать защитнику
Большинство уязвимостей — это не «забыли поставить библиотеку», а «никто не сформулировал, что так делать нельзя». Use case описывает добросовестного пользователя; abuse case — противника с теми же входами, но злым намерением. Защитник, который мыслит кейсами злоупотребления, на этапе требований ловит классы проблем (доступ к чужим данным, инъекции, перебор), пока они стоят строчку в документе, а не инцидент. Это прямой способ закрыть «Insecure Design» из OWASP — спроектировать защиту до кода.
Требования безопасности рядом с функциональными
Каждое функциональное требование тянет за собой требования безопасности. Их пишут тем же языком, измеримо и проверяемо. Сравните функцию загрузки файла:
Функциональное:
Пользователь может загрузить изображение профиля (JPG/PNG, до 5 МБ).
Требования безопасности (рядом, не отдельным «потом»):
- проверять реальный тип файла, а не только расширение;
- ограничивать размер до 5 МБ (защита от DoS «тяжёлым» файлом);
- хранить файл вне веб-корня; имя генерировать, не брать от клиента;
- отдавать с безопасными заголовками, чтобы файл не исполнился;
- действие доступно только владельцу профиля (проверка прав).
Полезный приём — связать требования безопасности с категориями STRIDE и с OWASP Top 10: тогда у каждого требования понятно, какую угрозу оно закрывает. Хорошее требование безопасности конкретно и проверяемо: не «сделать загрузку безопасной», а «отклонять файлы, чей реальный MIME-тип не входит в белый список image/jpeg, image/png».
Abuse cases: думаем как противник
Кейс злоупотребления берёт обычный сценарий и спрашивает: «а если пользователь враждебен?». Метод прост: для каждого use case придумайте «злого двойника» и опишите ожидаемую реакцию системы.
Use case: пользователь смотрит свой заказ по ссылке /orders/42
Abuse case: атакующий меняет 42 на 43, 44, 45... — перебирает чужие заказы
Ожидаемая реакция: сервер проверяет, что заказ принадлежит текущему
пользователю; чужой → 404/403, а не выдача данных
Use case: пользователь вводит промокод при оплате
Abuse case: атакующий шлёт тысячи кодов в секунду, подбирая валидные
Ожидаемая реакция: rate limiting + блокировка после N неудач
Use case: форма обратной связи отправляет письмо
Abuse case: атакующий вставляет в поле управляющие символы/инъекцию
Ожидаемая реакция: ввод валидируется и экранируется при использовании
Первый пример — это IDOR (небезопасная прямая ссылка на объект) и «broken access control» из самого верха OWASP. Записанный как abuse case на этапе требований, он почти наверняка будет реализован и протестирован правильно; не записанный — станет типовой дырой.
Как это работает под капотом
Кейс злоупотребления естественно превращается в проверку доступа на сервере. Уязвимая реализация достаёт объект по id из URL и сразу его отдаёт; безопасная — сперва убеждается, что объект принадлежит текущему пользователю.
# УЯЗВИМО (IDOR): отдаём заказ по id из URL без проверки владельца.
def get_order(order_id, current_user):
return db.orders.find(order_id) # вернёт и чужой заказ
# БЕЗОПАСНО: проверяем, что заказ принадлежит текущему пользователю.
def get_order(order_id, current_user):
order = db.orders.find(order_id)
if order is None or order.owner_id != current_user.id:
raise NotFound() # чужой → как будто не существует
return order
Видно, что abuse case и требование безопасности — это две стороны одного: сценарий «перебор чужих id» рождает требование «проверять владельца», а оно — конкретную проверку в коде. Если этот путь пройден на этапе дизайна, разработчику остаётся аккуратно его реализовать.
Security в Definition of Done
Чтобы требования безопасности не терялись, их включают в Definition of Done — критерий, по которому задача считается завершённой. Тогда «готово» означает не только «функция работает», но и «требования безопасности выполнены и проверены». Типичные пункты: ввод валидируется; доступ к объектам проверяет владельца/права; ошибки не раскрывают внутренности; критичные действия логируются; abuse cases из тикета покрыты тестами; зависимости без известных уязвимостей. Юридическая рамка остаётся прежней: проверять реализацию этих требований можно на своих и согласованных системах (ст. 272 УК РФ), а сами кейсы злоупотребления — это проектная работа, а не нападение.
Как защититься
Пишите требования безопасности рядом с функциональными, конкретно и проверяемо, связывая их со STRIDE и OWASP. Для каждого use case заводите «злого двойника» — abuse case — и фиксируйте ожидаемую реакцию системы. Особое внимание — доступу к объектам по id (IDOR), перебору и недоверенному вводу. Включите безопасность в Definition of Done, чтобы задача без выполненных требований безопасности не считалась завершённой. Так защита оказывается спроектированной до кода, а не достроенной после инцидента.
Итоги
- Требования безопасности пишутся рядом с функциональными — конкретно, измеримо, проверяемо.
- Abuse case — «злой двойник» use case: что сделает противник и как система обязана ответить.
- Классический abuse case — перебор чужих id (IDOR); ответ — проверка владельца на сервере.
- Полезно связывать требования безопасности со STRIDE и OWASP Top 10 — видно, какую угрозу закрывает каждое.
- Security в Definition of Done: «готово» = функция работает И требования безопасности выполнены и протестированы.