📚 Теория: IDOR и проверка владельца (раскрыть)
Почему появляется IDOR?
Разработчики доверяют идентификатору из URL и считают, что авторизация уже была. Приложение не проверяет, кому принадлежит ресурс.
⚠️ Пользователь просто меняет ID и скачивает чужие профили.
Какие последствия?
Раскрытие чужих персональных данных, нарушение ФЗ-152 и прозрачный путь к эскалации привилегий.
🔐 Нужно сопоставлять владельца ресурса и действующего пользователя.
Клиент отправляет /api/accounts/42, хотя сам владеет ID 11.
Контроллер берёт ID из URL и отдаёт профиль без доп.проверок.
Атака раскрывает ФИО, контакты, бонусные баллы другого клиента.
Как нужно: проверяйте право доступа на уровне сервиса: запросом findByIdAndOwner, сравнением accountId с currentUser.getAccountId(), а также добавьте централизованный Access Decision Manager.
Контекст
Команда добавила журналирование доступа и решила, что авторизация уже настроена. Однако идентификатор передаётся напрямую из URL, и любой авторизованный клиент может запросить чужой профиль.
- Проверь, как контроллер использует
accountIdиз пути. - Подумай, где должна находиться проверка владения — в контроллере, сервисе или фильтре.
- Опиши рекомендацию: запрос по паре
accountId + tenant, RBAC или ACL.
Сниппет
Code Review
Референс-исправление
Нужно проверять, что ресурс принадлежит текущему пользователю. Используйте сервис с методом findByIdAndOwner или фильтруйте по currentUser.
Флаг ревью: FLAG{java-idor-account-review}
public ResponseEntity<AccountDto> getAccount(Long accountId, AppUser currentUser) {
Account account = accountRepository
.findByIdAndOwner(accountId, currentUser.getId())
.orElseThrow(() -> new AccessDeniedException("account mismatch"));
auditLogger.logProfileAccess(currentUser.getUsername(), accountId);
return ResponseEntity.ok(mapper.toDto(account));
}
Добавьте интеграцию с Access Decision Manager, ограничение на уровне ORM и аудит всех отказов. Для фронтенда используйте токен с клеймом владельца.
Проверка флага
После ревью зафиксируй флаг, чтобы дашборд засчитал лабораторию.