Bug2Lab · Secure Code · Java / Spring Security

Отсутствие авторизации на админ-эндпоинте

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

1
Как выглядит атака
Любой пользователь вызывает:
GET /admin/exportUsers
и получает CSV со всеми клиентами, их email и статусами. Это должно быть доступно только админу, но доступно всем.
GET /admin/exportUsers
200 OK (text/csv)
userId,email,isVip
101,ceo@company.example,true
102,client@example.com,false
...
2
Почему это стало возможным
Контроллер не проверяет роль. Нет ни фильтра безопасности, ни аннотации @PreAuthorize. То есть приложение НЕ спрашивает «а ты вообще админ?».
Проблемный код
41 @GetMapping("/admin/exportUsers")
42 public String exportUsers() {
43 return userService.exportAllToCsv(); // ❌ без проверки прав
44 }
3
Как это чинится правильно
Требуем роль явно. Если роль не совпадает — 403. Это стандарт: любой «админ»-эндпоинт должен быть явно защищён.
Исправленный паттерн
41 @PreAuthorize("hasRole('ADMIN')")
42 @GetMapping("/admin/exportUsers")
43 public String exportUsers() {
44 return userService.exportAllToCsv(); // ✅ только ADMIN
45 }

bug2regress Регрессионный тест (стоп-кран)

В регрессе мы пытаемся вызвать админ-эндпоинт обычным токеном. Если видим 200 и CSV — стопаем релиз. Ожидаем 403.

#!/bin/bash
# admin-access-check.sh
# Обычный пользователь НЕ должен иметь доступ к /admin/exportUsers

TOKEN_USER="Bearer user-token"

STATUS=$(curl -s -o /tmp/out.csv -w "%{http_code}" \
  -H "Authorization: $TOKEN_USER" \
  https://staging.example.internal/admin/exportUsers)

if [ "$STATUS" = "200" ]; then
  echo "[BLOCK] /admin/exportUsers доступен без роли ADMIN!"
  exit 1
fi

echo "[OK] /admin/exportUsers защищён (HTTP $STATUS)"
exit 0

Этот тест — гарантия, что «случайно забыли @PreAuthorize» никогда не уедет в прод без вашего ведома.

Проверка понимания Что было корнем проблемы?

Стандарт после этой лабораторной: любой эндпоинт с административными данными должен иметь явную проверку роли. И это проверяется регресс-тестом в пайплайне.

Теория (по желанию) Почему «открытый» админ-эндпоинт = репутационный ад