Материал

Как не сломать доступы при добавлении новой функции

Практическое руководство для команд, которые хотят выпускать фичи быстро и не платить за это безопасностью

Введение: почему доступы ломаются именно при добавлении новых фич

Разработчик добавляет новый API-эндпоинт. Функция работает корректно — данные приходят, бизнес-логика выполняется, тесты зелёные. PR проходит ревью. Через неделю на пентесте или в bug bounty оказывается, что эндпоинт доступен без авторизации, или что обычный пользователь может вызвать его с чужим user_id, или что роль viewer может делать мутации.

Это не редкость. По данным OWASP, нарушения контроля доступа фиксируются буквально в каждом приложении, которое проходит профессиональное тестирование [1]. Среднее количество инцидентов по этой категории в 2025 году — 3,74% от всех эндпоинтов, а суммарное количество зафиксированных случаев превышает 1,8 миллиона [1][8].

Механика почти всегда одинакова: доступы не «взламывают» в кинематографическом смысле — их просто не добавляют [5][9]. Новая функция появляется в продакшне раньше, чем кто-то успевает спросить: «А кому вообще разрешено это делать?»

Эта статья — практическое руководство для Tech Lead, разработчика и AppSec-специалиста о том, как выстроить процесс, при котором авторизация новых функций проверяется до merge и до релиза, а не после инцидента.

Часть 1. Что именно ломается и почему

Аутентификация vs авторизация: разница, которую часто не замечают

Аутентификация отвечает на вопрос «кто ты?» — токен, пароль, биометрия, сессия. Авторизация отвечает на вопрос «что тебе разрешено?» — роль, атрибуты, политики, контекст [2].

На практике команды хорошо выстраивают аутентификацию: JWT, OAuth 2.0, MFA — всё это внедрено, документировано и проверяется в тестах. Авторизация уходит на второй план. Разработчик видит, что пользователь аутентифицирован, и подсознательно считает, что этого достаточно. Ворота в здание проверяются; двери внутри — нет [7].

Типовые точки отказа при разработке новых функций

Когда команда добавляет новую фичу, доступы ломаются в нескольких типовых сценариях.

Первый — новый эндпоинт без проверки роли. Разработчик создаёт POST /api/v1/reports/export, подключает middleware аутентификации, но забывает добавить проверку роли. Эндпоинт доступен любому аутентифицированному пользователю, включая viewer [6].

Второй — IDOR (Insecure Direct Object Reference). Эндпоинт принимает ?account_id=12345 и возвращает данные без проверки, что этот аккаунт принадлежит текущему пользователю. Атакующий перебирает идентификаторы и получает чужие данные. Именно через IDOR в 2023 году утекли данные почти 10 миллионов клиентов Optus [7].

Третий — вертикальная эскалация привилегий. Рефакторинг старого middleware или изменение структуры ролей ломает существующую логику. Пользователь manager получает доступ к функциям admin — или наоборот, admin теряет часть доступов при деплое.

Четвёртый — авторизация только на уровне UI. Кнопка «Удалить» спрятана для роли viewer, но DELETE /api/v1/resource/:id вызвать напрямую никто не мешает [14]. Браузер не является слоем защиты.

Пятый — авторизация в frontend-компонентах (актуально для Server Actions в Next.js и аналогов). Каждый Server Action должен быть самодостаточным с точки зрения безопасности — не полагаться на то, что его вызовут из «правильного» места [20]. Изменение флоу или маршрута может оставить Action открытым.

Шестой — CORS, настроенный слишком широко. При добавлении нового публичного эндпоинта разработчик ставит Access-Control-Allow-Origin: * для удобства отладки, и это уходит в продакшн [17].

Часть 2. Модели авторизации: RBAC, ABAC, ReBAC

Выбор модели — это не техническая деталь

OWASP Authorization Cheat Sheet прямо указывает: решение о модели авторизации должно приниматься на этапе проектирования, до написания кода. От него зависит весь SDLC [10].

Распространённая ошибка — начать с простых if user.role == 'admin' внутри бизнес-логики, а потом масштабировать это вручную. Когда ролей становится 10, а правил — 50, код превращается в нечитаемый лабиринт условий. При добавлении новой функции разработчик не понимает, какую ветку добавить, и добавляет неправильную — или не добавляет никакой.

RBAC: просто, предсказуемо, но масштабируется плохо

Role-Based Access Control привязывает разрешения к ролям: admin, editor, viewer. Понятна, легко объясняется команде, хорошо работает для простых иерархий.

Проблема — «взрыв ролей» (role explosion). Когда бизнес требует «менеджер проекта A может редактировать, менеджер проекта B — только просматривать», роли начинают размножаться: project_a_manager, project_b_manager. При добавлении новой функции разработчик должен явно обновить каждую роль. Пропуск одной — регрессия [18].

ABAC: гибко, но сложнее тестировать

Attribute-Based Access Control принимает решение о доступе на основе атрибутов пользователя, ресурса и контекста: время суток, геолокация, уровень чувствительности данных. Модель мощная, но трудно поддаётся ручному ревью — цепочки условий неочевидны [13].

При добавлении новой функции нужно явно описать, какие атрибуты влияют на доступ к ней. Если это не задокументировано в политике, атрибут может не проверяться вовсе.

ReBAC: для сложных граф-структур

Relationship-Based Access Control (модель Google Zanzibar, реализации OpenFGA, SpiceDB) строит авторизацию на основе отношений между объектами: «пользователь является участником команды, которая имеет доступ к документу». Решает проблемы RBAC в задачах collaborative permissions, но требует более сложной инфраструктуры [20].

OpenFGA в октябре 2025 года перешёл в статус CNCF Incubating project, что означает зрелость для продакшн-использования [12][20].

Декларативные политики — лучше, чем if-условия в коде

Общий тренд 2024–2026 годов: выделять авторизационную логику в отдельный слой — политику. Инструменты вроде Cerbos, Oso, Cedar, Casbin позволяют описывать правила декларативно, версионировать их как код и тестировать независимо от бизнес-логики [18]. При добавлении новой функции разработчик добавляет правило в политику — и оно автоматически применяется ко всем проверяющим точкам. Этот подход называется Policy-Based Access Control (PBAC) [18].

Часть 3. Deny-by-default и серверная проверка

Принцип, без которого всё остальное не работает

OWASP формулирует это однозначно: кроме публичных ресурсов, доступ запрещён по умолчанию [17]. Если разработчик не добавил явное разрешение — ресурс недоступен. Это контрастирует с практикой «открыть по умолчанию, закрыть потом» — при которой новая функция публично доступна до момента, когда кто-то вспомнит добавить ограничение.

На практике это означает несколько вещей.

Middleware авторизации должен быть включён глобально. Отдельные маршруты явно помечаются как публичные, а не наоборот. Иначе разработчик, который добавляет новый роутер, по умолчанию делает его открытым [13].

Проверка должна происходить на сервере. UI-элементы (скрытые кнопки, отключённые поля) — вспомогательная мера, а не защита [14][11]. Атакующий вызывает API напрямую, минуя интерфейс.

Авторизация должна проверяться в каждой операции, а не только при входе. Аутентификация токена при логине не даёт автоматического разрешения на каждый последующий запрос — особенно при работе с чужими объектами [16].

Часть 4. Авторизация как часть разработки: как встроить в процесс

Требования на этапе проектирования

Прежде чем написать первую строчку кода для новой функции, команда должна ответить на три вопроса:

  1. Кто может вызывать эту функцию? (роль, атрибут, отношение)
  2. Владение: может ли пользователь действовать только со своими объектами или с чужими тоже?
  3. Что произойдёт, если проверка не пройдена? (403 Forbidden, редирект, лог-событие)

Эти ответы должны стать частью задачи или спецификации. Если их нет — задача не готова к разработке.

Тесты авторизации как первичные граждане

OWASP Web Security Testing Guide указывает: проверки авторизации должны быть частью юнит- и интеграционных тестов наравне с функциональными [4].

Минимальный набор тестов для каждого нового эндпоинта:

  1. Запрос без токена — ожидаем 401.
  2. Запрос с токеном пользователя, у которого нет нужной роли — ожидаем 403.
  3. Запрос с корректной ролью, но чужим resource_id — ожидаем 403 (IDOR-проверка).
  4. Запрос с корректной ролью и своим resource_id — ожидаем 200.

Эти тесты должны быть автоматическими и запускаться в CI на каждый PR. Ручное QA не заменяет автоматику — ревьюер пропустит, QA-инженер не проверит все роли.

Code review: что смотреть в новом PR

При ревью PR с новыми API-эндпоинтами или изменением логики доступа стоит проверять несколько вещей.

Есть ли явная проверка авторизации на каждом новом эндпоинте? Если middleware стоит глобально — убедиться, что новый роутер его не обходит.

Есть ли проверка владения объектом, а не только проверка роли? Роль editor позволяет редактировать документы — но только свои или чужие тоже?

Используется ли параметр из запроса (URL, body) без верификации? ?user_id=123 — это классический IDOR, если сервер не сравнивает с current_user.id [17].

Изменяет ли PR существующие роли или политики? Рефакторинг роли может сломать права в других частях системы.

Добавлены ли тесты для «негативных» сценариев — что запрещено, а не только что разрешено?

CORS и конфигурация

При добавлении публичных или cross-origin эндпоинтов CORS должен быть настроен явно: конкретные домены, а не *. OWASP отмечает misconfiguration CORS как одну из типовых форм Broken Access Control [17]. Открытый CORS позволяет атакующему делать запросы от имени аутентифицированного пользователя с произвольного домена.

Часть 5. Zero Trust и принцип минимальных привилегий

Почему «доверяй внутренней сети» больше не работает

NIST SP 800-207 фиксирует: Zero Trust Architecture исходит из того, что нет неявного доверия ни к пользователям, ни к устройствам, ни к сервисам — только потому что они находятся «внутри» сети [15]. Каждый запрос аутентифицируется и авторизуется независимо.

Для разработки это означает: внутренний микросервис не должен получать автоматический доступ к данным другого микросервиса только потому, что они «в одной сети». Каждый вызов требует авторизации.

При добавлении нового сервиса или функции команда определяет минимально необходимые разрешения (Principle of Least Privilege) — и выдаёт только их [15]. Разрешения не накапливаются по умолчанию; они явно назначаются для конкретной операции.

Практика PoLP при разработке новых функций

Принцип минимальных привилегий применяется не только к пользователям, но и к сервисным аккаунтам, API-ключам, CI/CD-агентам и machine identities [15].

Типовая ошибка: для нового сервиса создаётся один «удобный» service account с широкими правами — чтобы не возиться с гранулярной настройкой. В итоге компрометация одного компонента даёт атакующему доступ ко всему, что доступно этому аккаунту. В 2024 году инцидент с Amazon ECS показал, как злоупотребление IAM-ролями с избыточными правами позволило атакующему эскалировать привилегии в облачной инфраструктуре [19].

Часть 6. Чек-лист: что проверять до merge и до релиза

До написания кода

  • Авторизационные требования описаны в задаче: кто может, кто не может, что происходит при отказе.
  • Определена модель: RBAC/ABAC/ReBAC, политика описана или обновлена.
  • Рассмотрен вопрос владения объектами: нужна ли проверка owner_id == current_user.id.

В коде

  • Каждый новый эндпоинт явно проверяет авторизацию на сервере, а не только в UI.
  • Нет доверия к параметрам из запроса без верификации (URL-параметры, body, заголовки).
  • Централизованный middleware авторизации не обходится; если нужно публичное исключение — оно явно задокументировано.
  • CORS настроен для конкретных доменов, а не открыт широко.
  • Нет debug-флагов или временных // TODO: add auth check в продакшн-ветке.

В тестах

  • Тесты покрывают «запрещённые» сценарии: нет токена, не та роль, чужой объект.
  • Тесты запускаются в CI на каждый PR.
  • При изменении ролей или политик — регрессионные тесты для всех затронутых путей.

В PR-ревью

  • Ревьюер явно проверяет авторизацию нового кода — не только бизнес-логику.
  • Изменения, затрагивающие модель ролей или middleware, требуют ревью от security-компетентного участника.

Перед релизом

  • Если функция добавляет новые API — проведено smoke-тестирование на staging с разными ролями.
  • Логирование авторизационных отказов настроено: 403-ответы должны быть видны в мониторинге, а не теряться.

Часть 7. Типичные ошибки и как их избежать

Ошибка 1: «Прячем в UI — значит закрыли»

Скрытые кнопки, disabled-поля, отсутствие ссылки в меню не защищают эндпоинт. Любой инструмент для работы с HTTP (curl, Burp Suite, Postman) позволяет вызвать API напрямую. Проверка авторизации должна быть только серверной [14].

Ошибка 2: Проверяем вход, не проверяем каждую операцию

Пользователь аутентифицировался — это не разрешение на каждый последующий запрос. При операциях с конкретными объектами нужно проверять, что объект принадлежит текущему пользователю или пользователь имеет явное разрешение на него. NIST SP 800-207 фиксирует: «авторизация к одному ресурсу не даёт автоматического доступа к другому» [16].

Ошибка 3: Авторизация разбросана по коду

Когда проверки авторизации встроены в бизнес-логику через if role == 'admin' в десятках мест, добавление новой функции требует обновления каждого места. Что-то неизбежно пропускается. Централизованный слой авторизации (middleware, policy engine) решает эту проблему: новое правило описывается один раз и применяется везде [17].

Ошибка 4: Нет тестов на «что запрещено»

Большинство тестов проверяют happy path — что авторизованный пользователь может делать. Тесты на запрещённые сценарии (неверная роль, чужой объект, отсутствующий токен) часто отсутствуют. Именно они ловят регрессии при рефакторинге [4].

Ошибка 5: Service accounts с широкими правами

Для нового сервиса или CI/CD-агента создаётся сервисный аккаунт с правами admin «для простоты». Принцип минимальных привилегий требует давать только то, что нужно для конкретной операции [15].

Ошибка 6: Feature flags как скрытая авторизация

Feature flag скрывает новую функцию от пользователей в UI. Но если API-эндпоинт уже задеплоен — он доступен независимо от флага. Feature flag не заменяет авторизацию.

Часть 8. Авторизация в AI-кодинге: новые риски

Скорость разработки с AI-ассистентами растёт — и с ней растёт риск появления эндпоинтов, написанных быстро, но без явной авторизационной логики. AI-генерированный код часто реализует функциональность корректно, но опускает security-слой: он не знает, какая роль должна иметь доступ, если это не описано в промпте.

PR, написанный с помощью AI, может содержать полностью рабочий CRUD-эндпоинт без единой строки авторизации. «Работает» не значит «безопасно для merge» — это разные утверждения.

Для команд, которые используют AI-кодинг, важно встроить контроль именно на уровне изменения, а не откладывать его до пентеста или аудита. Инструменты вроде HighVibe анализируют конкретное изменение в PR — код, конфигурацию, служебные файлы — и помогают заметить риск до merge: отсутствующие проверки авторизации, открытый CORS, debug-настройки в production-конфиге. Это не замена SAST/SCA, а дополнительный слой контроля, ориентированный именно на контекст изменения и релиза.

Часть 9. Тренды 2025–2026

Authorization as infrastructure

Выделение авторизации в отдельный слой инфраструктуры — нарастающий тренд. OpenFGA (CNCF Incubating), Cedar (AWS), Cerbos, Oso — инструменты, позволяющие описывать политики декларативно, тестировать их как код и применять единообразно через весь стек [20]. При добавлении новой функции разработчик добавляет правило в политику, а не встраивает условие в код.

AI Agent Authorization

В 2025–2026 годах появилась новая задача: авторизация не только людей, но и AI-агентов. Amazon Bedrock AgentCore Policy, интеграции LangChain с SpiceDB, Oso с функциями risk control для coding agents — индустрия начала решать, что может делать AI-агент от имени пользователя [20]. При разработке функций, которые будут вызываться агентами, авторизационная модель должна учитывать machine identities наравне с человеческими.

Continuous authorization

Вместо одноразовой проверки при входе — постоянная верификация контекста при каждом запросе: поведение пользователя, состояние устройства, аномалии [15]. Это принцип Zero Trust в действии: авторизация не накапливается, а вычисляется в реальном времени.

Заключение: что делать дальше

Broken Access Control остаётся самой распространённой уязвимостью приложений не потому, что её сложно исправить — а потому что её легко не заметить при высоком темпе разработки. Каждый новый эндпоинт, каждый рефакторинг ролей, каждый новый сервис — потенциальная точка регрессии доступов.

Практические следующие шаги для команды:

  1. Провести аудит существующих эндпоинтов: есть ли на каждом явная проверка авторизации?
  2. Внедрить deny-by-default в middleware: новые роуты публичны только если явно помечены.
  3. Добавить в definition of done проверку авторизационных требований до начала разработки.
  4. Написать автоматические тесты на «запрещённые» сценарии и включить их в CI.
  5. При использовании AI-кодинга — убедиться, что ревью PR включает явную проверку наличия авторизационной логики.

Быстро выпустить функцию и выпустить её безопасно — не противоречие. Это вопрос встроенного процесса.

Источники

[1] OWASP Foundation — «A01:2025 Broken Access Control» — https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/

[2] PortSwigger Web Security Academy — «Access control vulnerabilities and privilege escalation» — https://portswigger.net/web-security/access-control

[3] Oso — «RBAC vs ABAC vs PBAC: Understanding Access Control Models in 2025» — https://www.osohq.com/learn/rbac-vs-abac-vs-pbac

[4] OWASP Web Security Testing Guide — «Security Tests Integrated in Development and Testing Workflows» — https://owasp.org/www-project-web-security-testing-guide/latest/2-Introduction/

[5] Parasoft — «OWASP Top 10 2025: What Changed & Why It Matters» — https://www.parasoft.com/blog/owasp-top-10/

[6] Xygeni — «OWASP Top 10 2025 Explained for Developers» — https://xygeni.io/blog/owasp-top-10-2025-explained-for-developers/

[7] IntelligenceX — «Broken Access Control (A01:2025): Complete Guide» — https://blog.intelligencex.org/broken-access-control-owasp-a01-2025-complete-guide

[8] Cerbos — «Broken Access Control Still Tops the List: OWASP Top 10 2025» — https://www.cerbos.dev/blog/broken-access-control-owasp-top-10-2025

[9] BSG Tech — «OWASP Top 10 2025: What Changed and Why It Matters» — https://bsg.tech/blog/owasp-top-10/

[10] OWASP Cheat Sheet Series — «Authorization Cheat Sheet» — https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html

[11] Authgear — «What is Broken Access Control Vulnerability and How to Prevent It» — https://www.authgear.com/post/what-is-broken-access-control-vulnerability-and-how-to-prevent-it/

[12] DEV Community — «RBAC vs ABAC vs ReBAC: How to Choose and Implement Access Control Models» — https://dev.to/kanywst/rbac-vs-abac-vs-rebac-how-to-choose-and-implement-access-control-models-3i2d

[13] Escape Tech — «Access Control Models: RBAC, ABAC, DAC» — https://escape.tech/blog/access-control-models/

[14] PortSwigger — «Access control vulnerabilities» (Web Security Academy) — https://portswigger.net/web-security/access-control

[15] NIST — «SP 800-207: Zero Trust Architecture» — https://csrc.nist.gov/pubs/sp/800/207/final

[16] CyberArk — «What Is NIST SP 800-207?» — https://www.cyberark.com/what-is/nist-sp-800-207-cybersecurity-framework/

[17] BrightSec — «Broken Access Control: Examples and 4 Defense Tips» — https://brightsec.com/blog/broken-access-control-attack-examples-and-4-defensive-measures/

[18] Securityium — «Mastering Access Control Vulnerabilities and Privilege Escalation» — https://www.securityium.com/mastering-access-control-vulnerabilities-and-privilege-escalation/

[19] Aviatrix — «Amazon ECS 2024 Privilege Escalation Exposes IAM Identity Hijacking» — https://aviatrix.ai/threat-research-center/amazon-ecs-2024-privilege-escalation-iam-hijacking/

[20] Habr / Simbirsoft — «Архитектура безопасности во frontend-приложениях: Server Actions и защита данных в Next.js» — https://habr.com/ru/companies/simbirsoft/articles/1039136/

Нужен такой же контроль в ваших изменениях и релизах?

Покажем пример такого замечания на вашем сценарии и соберём пилотный контур без лишней суеты.

Запросить пилот Все статьи
Дальше по теме

Ещё материалы

Все статьи
24 июня 2026 18 мин

Политика использования ИИ в команде разработки: как не опоздать, когда всё уже идёт

Если разработчики уже пишут код с ИИ ассистентами, политика нужна сегодня — а не после первого инцидента TL;DR Более 84% разработчиков уже используют или планируют использовать ИИ инструменты 1 , и большинство делают эт…

Открыть материал
23 июня 2026 16 мин

Регистрация и онбординг пользователей: где появляются первые уязвимости

Форма регистрации выглядит просто. За ней скрывается один из наиболее атакуемых периметров приложения. TL;DR Форма регистрации и онбординг флоу — это первая поверхность атаки, которую видит злоумышленник. Большинство уя…

Открыть материал
23 июня 2026 15 мин

Бизнес-логика и мошенничество в продукте: что проверять до запуска

Ваш продукт работает правильно. Но это не значит, что он работает безопасно. TL;DR Уязвимости бизнес логики — это не сломанный код, а сломанные правила: приложение делает именно то, что написано, но не то, что задумывал…

Открыть материал