Назад в блог
Web Security4.07.2026

Broken Access Control (OWASP A01:2021): риск №1 для веб-приложений

Broken Access Control (нарушение контроля доступа) занимает позицию A01:2021 в рейтинге OWASP Top 10 — это риск номер один для веб-приложений. В 2017 году он был на пятом месте; подъём объясняется его распространённостью и высоким воздействием: OWASP установил, что 94% протестированных приложений содержали ту или иную форму этой уязвимости, и на эту категорию приходится больше вхождений Common Weakness Enumeration (CWE), чем на любую другую. Контроль доступа начинается там, где заканчивается аутентификация: аутентификация подтверждает, кто вы; контроль доступа решает, что вам разрешено делать. Когда таких решений нет, они неполны или проверяются только в браузере, атакующий может прочитать или изменить данные и функции, которые должны быть недоступны.

Что на самом деле обеспечивает контроль доступа

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

  • Горизонтальная эскалация — пользователь получает доступ к ресурсам другого пользователя того же уровня привилегий. Пример: пользователь A открывает /api/orders/1043, меняет ID на 1044 и читает заказ пользователя B. Та же роль, другой владелец.
  • Вертикальная эскалация — пользователь получает возможности более высокого уровня привилегий. Пример: обычный пользователь вызывает POST /api/admin/users для создания аккаунтов или подменяет скрытое поле role=admin. Совершенно другая роль.

Распространённые шаблоны уязвимостей

IDOR / BOLA (Insecure Direct Object Reference / Broken Object Level Authorization). Это флагманская ошибка горизонтальной эскалации, а как BOLA она занимает позицию API1:2023 в OWASP API Security Top 10. Приложение раскрывает прямую ссылку на объект — идентификатор в базе данных, имя файла, UUID — и доверяет клиенту передавать лишь те ссылки, которыми он владеет. Поскольку сервер никогда повторно не проверяет владение, подмена идентификатора возвращает чужие данные. Предсказуемые последовательные идентификаторы (?invoice=8801) делают перебор тривиальным, но учтите: замена их на UUID — это обфускация, а не контроль. Решение — проверка владения на стороне сервера, а не неугадываемый идентификатор.

Отсутствие авторизации на уровне функций. Административные или привилегированные функции защищены лишь тем, что ссылка не показывается в интерфейсе. Сам endpoint не проверяет роль. Атакующий, знающий или угадавший /admin/delete-user — часто легко находимый в JavaScript-бандлах или через фаззинг — вызывает его напрямую. Это соответствует CWE-285 (Improper Authorization) и CWE-862 (Missing Authorization).

Принудительный просмотр (forced browsing). Атакующий запрашивает URL, параметры или HTTP-методы, которые нигде не связаны ссылками, но всё равно обслуживаются. Прямой запрос /reports/2026/q1-confidential.pdf или отправка PUT/DELETE на endpoint, защищающий только GET, обходят контроль, предполагавший, что пользователи будут переходить лишь по предоставленным ссылкам. Частые находки — endpoint'ы метаданных, файлы резервных копий и отладочные маршруты.

Другие частые варианты: неправильная конфигурация CORS, открывающая API недоверенным источникам; JWT, чьи утверждения (например, role или sub) принимаются без проверки подписи; и mass-assignment, когда тело запроса задаёт поля (isAdmin, accountBalance), которые клиент никогда не должен контролировать.

Реальные последствия

Сбои контроля доступа не теоретические. Уязвимость USPS Informed Delivery 2018 года позволяла любому авторизованному пользователю запрашивать данные аккаунтов ~60 миллионов пользователей через неаутентифицированный параметр API — хрестоматийный BOLA. Утечка First American Financial 2019 года раскрыла 885 миллионов ипотечных записей через последовательные идентификаторы документов, не требовавшие вообще никакой аутентификации. По CVSS v3.1 такие проблемы часто набирают 8,0+ (High) — например, удалённо эксплуатируемый IDOR, раскрывающий конфиденциальные данные, набирает CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N = 6,5, приближаясь к 8–9, когда доступны также целостность или административные функции.

Как это тестировать

  • Дифференциальное тестирование двух аккаунтов. Создайте двух пользователей (и одного администратора). Перехватите запрос от аккаунта A, затем воспроизведите его с cookie/токеном сессии аккаунта B. Если B получает данные A — у вас ошибка горизонтального доступа. Инструменты вроде Autorize или Auth Analyzer в Burp Suite автоматизируют это сравнение.
  • Подмена параметров. Увеличивайте, уменьшайте и фаззьте каждый идентификатор объекта — ID, UUID, имена файлов, номера счетов — включая те, что в теле JSON и в утверждениях JWT.
  • Зондирование на уровне функций. Перечислите административные и привилегированные endpoint'ы из source map JS и брутфорсом каталогов, затем вызывайте их с низкопривилегированной сессией.
  • Тестирование методов и принудительного просмотра. Пробуйте альтернативные HTTP-глаголы и напрямую запрашивайте несвязанные ресурсы. Согласуйте охват с тест-кейсами OWASP WSTG-ATHZ (Authorization Testing).

Как это предотвратить

  • Запрещать по умолчанию (deny by default). Каждый ресурс приватен, пока правило явно не предоставит доступ. Публичные endpoint'ы — это исключение, которое вы добавляете в белый список, а не умолчание, которое забываете заблокировать.
  • Всегда проверяйте на стороне сервера. Проверки на стороне клиента — это UX, а не безопасность. Авторитетное решение должно приниматься на сервере, при каждом запросе, для каждого объекта.
  • Проверяйте владение, а не только роль. Убедитесь, что аутентифицированный субъект действительно владеет этой записью или имеет на неё право. Определяйте личность пользователя из сессии/токена — никогда из переданного клиентом параметра user_id.
  • Централизуйте логику. Направляйте все решения через единый компонент авторизации или middleware, а не разбрасывайте разрозненные проверки if. Это соответствует NIST SP 800-53 AC-3 (Access Enforcement) и принципу наименьших привилегий (AC-6).
  • Используйте косвенные ссылки и ограничивайте частоту. Предпочитайте ссылки, отображаемые per-сессия, логируйте сбои контроля доступа и оповещайте о повторных отказах, чтобы поймать перебор.
  • Тестируйте непрерывно. Добавьте автоматические тесты авторизации в CI, чтобы новый endpoint не мог попасть в продакшн без проверки владения.

Контроль доступа — это проектная работа, а не фильтр, приклеенный в конце. Явно моделируйте роли и владение объектами, обеспечивайте каждое решение на стороне сервера по принципу deny-by-default и проверяйте это тестированием двух аккаунтов при каждом релизе. Именно эта дисциплина превращает риск №1 из OWASP в незначительное событие.

OWASPaccess-controlIDORBOLAauthorization