В мире, где каждое второе приложение — это набор микросервисов, API стал главными воротами для данных. И главным вектором атак. Годами одной из самых критичных и распространенных уязвимостей остается Broken Object Level Authorization (BOLA), стабильно занимающая первое место в OWASP API Security Top 10. Эта уязвимость не требует сложных техник эксплуатации, но ведет к катастрофическим утечкам данных. В этом руководстве мы разберем BOLA от и до: от базовой теории до продвинутых техник тестирования и защиты, подкрепленных реальным опытом наших пентестов.
1. Что такое BOLA? Проще простого
BOLA (Broken Object Level Authorization) или Неисправный контроль авторизации на уровне объектов — это уязвимость, которая позволяет атакующему получить несанкционированный доступ к данным другого пользователя, манипулируя идентификатором объекта (ID) в API-запросе.
Классическая аналогия: Представьте, что у каждого клиента банка есть сейф. API — это администратор, который по вашей просьбе приносит вам ящик из сейфа. Уязвимость BOLA возникает, когда администратор не проверяет, ваш ли это сейф, а просто смотрит на номер ящика. Вы говорите «принесите ящик №123», и он приносит, даже если этот ящик принадлежит не вам.
BOLA vs IDOR: IDOR (Insecure Direct Object Reference) — это более широкое понятие, включающее несанкционированный доступ к любым объектам (файлам, записям в БД). BOLA — это частный, но самый распространенный случай IDOR, специфичный именно для API, где доступ к объектам осуществляется через их идентификаторы.
2. Как искать BOLA: Пошаговая методика пентестера
Поиск BOLA — это методология перебора и анализа. Вот алгоритм, который мы используем в работе.
Шаг 1: Разведка API
Первым делом необходимо понять структуру API. Для этого:
- Изучите документацию (Swagger/OpenAPI), если она есть.
- Используйте Burp Suite или OWASP ZAP для проксирования трафика мобильного приложения или веб-интерфейса.
- Ищите эндпоинты, которые работают с объектами:
/api/users/{id},/api/orders/{order_id},/api/docs/{document_id}.
Шаг 2: Поиск идентификаторов
В каждом запросе и ответе ищите параметры, которые могут быть идентификаторами:
- В URL:
GET /api/v1/users/321/profile - В теле запроса:
{"order_id": 7842} - В заголовках: Иногда в кастомных заголовках.
Шаг 3: Манипуляция и перебор
Найдя потенциальный ID, необходимо его изменить и посмотреть на ответ сервера.
- Пример уязвимого запроса:httpGET /api/v1/users/123/orders HTTP/1.1 Host: target.com Authorization: Bearer <token_user_A>Этот запрос возвращает заказы пользователя с ID 123.
- Действие пентестера: Заменить
123на124и отправить запрос повторно.httpGET /api/v1/users/124/orders HTTP/1.1 Host: target.com Authorization: Bearer <token_user_A>
Шаг 4: Анализ ответа
- Уязвимость есть, если: Сервер возвращает HTTP 200 OK и данные заказов пользователя с ID 124.
- Уязвимости нет, если: Сервер возвращает HTTP 403 Forbidden или HTTP 404 Not Found.
Важно: Иногда сервер возвращает 200 OK, но с пустым телом ответа, если объект не найден. Это тоже признак отсутствия уязвимости.
3. Практические примеры эксплуатации BOLA
Пример 1: Кража персональных данных
- Эндпоинт:
GET /api/patients/{patient_id}/medical_records - Эксплуатация: Атакующий последовательно перебирает
patient_id(1, 2, 3…). Каждый успешный ответ — это получение полной медицинской истории случайного пациента.
Пример 2: Обход многоуровневой авторизации (Advanced BOLA)
Представьте API для SaaS-платформы:
GET /api/company/{company_id}/project/{project_id}/document/{doc_id}
Сервер может проверять, имеет ли пользователь доступ кcompany_id, но ленится проверить права на конкретныйproject_idилиdoc_idвнутри компании. Атакующий, имея доступ к одной компании, может подобрать ID проектов и документов из других компаний.
4. Инструменты для автоматического тестирования
Ручной тест эффективен, но для глубокого аудита нужна автоматизация.
- Burp Suite Professional:
- Автоматическое сканирование: Burp Scanner умеет находить простые случаи BOLA.
- Плагин Autozie: Позволяет автоматизировать перебор ID, работая через браузер.
- Ручное тестирование с Intruder: Мощнейший инструмент для перебора параметров. Настраиваете позицию атаки на ID и запускаете атаку типа Sniper или Cluster bomb.
- OWASP ZAP: Активный сканер также может обнаружить BOLA, но часто требует ручной настройки контекста и аутентификации.
- Самописные скрипты на Python (с библиотеками requests, threading):
- Для чего: Для массового и быстрого перебора тысяч ID, когда нужно проверить всю базу.
- Преимущество: Полный контроль над логикой атаки и обход WAF.
5. Мой опыт: Типичные сценарии и ошибки, которые мы находим
За годы пентестов мы проверили сотни API. Вот главные паттерны, leading to BOLA:
- «Он же авторизован!» Самая частая ошибка в менталитете разработчика. Команда проверяет, что пользователь авторизован (валидный JWT-токен), но забывает проверить, имеет ли он право на доступ к конкретному объекту, ID которого пришел в запросе. Проверка аутентификации != Проверка авторизации.
- Провал в сложных цепочках. Как в примере выше (
/company/123/project/456/doc/789). Сервер проверяет права доступа к компании 123, но для проекта 456 внутри нее уже не проверяет, считая, что раз пользователь имеет доступ к компании, то имеет доступ ко всему внутри. Это фатальная ошибка логики. - Слабые идентификаторы. Использование последовательных, предсказуемых ID (1, 2, 3…) вместо UUID. Это не причина уязвимости, но ее катализатор. Сложно эксплуатировать BOLA, если ID выглядят как
f47ac10b-58cc-4372-a567-0e02b2c3d479. Легко — когда этоorder_id=7842. - Тихий отказ. Сервер возвращает HTTP 200 с пустым телом (
[]илиnull) при попытке доступа к несуществующему или недоступному объекту. Это плохая практика, которая усложняет тестирование, но не является защитой. Опытный пентестер будет сравнивать ответы, а не只看 статус-код.
Наш вердикт: BOLA — это не техническая сложность, а невнимательность и пробелы в проектировании системы авторизации.
6. Как защититься: Руководство для разработчиков
Исправление BOLA — это не про клейкую ленту, а про архитектуру.
- Единый центр авторизации. Не распыляйте проверки прав по всем контроллерам. Создайте единый сервис (микросервис), который получает на вход
user_idиobject_idи возвращаетhas_access: true/false. Используйте его на каждом эндпоинте. - Проверяйте права ВСЕГДА. На каждом запросе, который работает с объектом, должна быть проверка прав. Без исключений.
- Используйте непредсказуемые идентификаторы. Замените последовательные ID на UUID (Universally Unique Identifier). Это не панацея, но сильно усложняет массовый перебор.
- Возвращайте правильные коды ошибок. Если доступ запрещен — HTTP 403 Forbidden. Если объект не найден (и это не должно быть известно пользователю) — HTTP 404 Not Found. Никогда не возвращайте 200 с данными чужого объекта.
- Регулярно проводите код-ревью и пентесты. Специально ищите в коде места, где идет работа с ID из запроса, и проверяйте, что рядом есть проверка прав.
Пример кода middleware на Python (псевдокод):
def check_object_access(user_id, object_id, object_type):
# ... Логика проверки в базе данных, что user_id имеет доступ к object_id типа object_type
if not has_access:
raise PermissionDeniedException("Access denied")
# В обработчике запроса
@route('/api/users/<user_id>/orders')
def get_orders(user_id):
# Проверяем, что текущий аутентифицированный пользователь имеет доступ к заказам этого user_id
check_object_access(current_user.id, user_id, 'user')
# ... только потом получаем данные
orders = get_orders_from_db(user_id)
return jsonify(orders)
Заключение: BOLA — это лакмусовая бумажка зрелости команды
Наличие уязвимости BOLA в API — это яркий маркер того, что в процессе разработки не было культуры безопасности. Это ошибка, которую невозможно допустить, если авторизация была заложена в архитектуру с самого начала.
Ключевой вывод: Борьба с BOLA — это не про один исправленный баг. Это про внедрение процесса, при котором проверка прав на уровне объектов становится такой же обязательной, как и проверка аутентификации.
