📚 Теория: IDOR и методовая авторизация (раскрыть)
Где ломается безопасность?
Контроллер берёт идентификатор из URL, вызывает сервис и возвращает чужой профиль. Авторизация «планировалась» через @PreAuthorize, но её отключили.
⚠️ Любой пользователь меняет {id} и получает данные соседа.
Как исправить?
Верните методовую проверку: @PreAuthorize(\"hasRole('ADMIN') or #principal.id == #id\"). На уровне сервиса продублируйте ownership check.
🔐 Используйте SpEL, ACL, и централизованную проверку в слое бизнес-логики.
Клиент запрашивает /api/v1/users/42, хотя владеет только ID 7.
Метод контроллера не проверяет, что principal.id == id.
Возвращаются чужие персональные данные, нарушая GDPR/152-ФЗ.
Как надо: включите методовую защиту, проверяйте владельца в сервисе, добавьте негативные тесты с spring-security-test и аудит отказов.
Контекст
Команда временно сняла аннотацию безопасности, чтобы «ускорить демо». В релиз код ушёл без проверки владельца и роли. Теперь любой аутентифицированный пользователь видит чужой профиль.
- Пойми, как
UserControllerиспользуетidиз пути. - Предложи исправление:
@PreAuthorize, кастомныйAuthorizationManager, тесты. - Подготовь рекомендации по негативным тестам для чужих токенов.
Сниппет
Code Review
Референс-исправление
Контроллер должен запрещать доступ чужим пользователям. Верните методовую проверку и продублируйте guard в сервисе.
Флаг ревью: FLAG{java-idor-preauthorize-review}
@PreAuthorize("hasAuthority('PROFILE:READ') and #principal.id == #id")
public ResponseEntity<UserProfileDto> getUser(Long id, AppUser principal) {
UserProfile profile = userProfileService.requireOwnedProfile(id, principal);
return ResponseEntity.ok(mapper.toDto(profile));
}
Добавь негативные тесты с spring-security-test: используйте with(user("mallory").roles("USER")) и проверяйте 403 при запросе чужого ID.
Проверка флага
После ревью зафиксируй флаг, чтобы дашборд засчитал лабораторию.