📚 Теория: Валидация и Regex DoS (раскрыть)
Катастрофический бэктрекинг
Регулярки с вложенными квантификаторами ((\\w+\\.?)+) перебирают экспоненциально много путей. Одна длинная строка подвесит поток.
⚠️ DoS по CPU — типичная атака на валидацию форм.
Как защититься?
Используй встроенные валидаторы (@Email, @Pattern с детерминированными шаблонами), ограничивай длину (@Size), включай rate limiting и pre-validation (например, String.length()).
🔐 Для критичных сценариев — токены, очереди, отдельный воркер.
Атакующий шлёт 100 КБ строки "aaaaaaaa...!".
Регексп срабатывает в @Pattern, JVM перебирает миллионы комбинаций.
Поток завис, пулы исчерпаны, сервис недоступен.
Как надо: ограничивай данные на уровне HTTP и DTO, переписывай регекспы в DFA (без вложенных квантификаторов), оборудуй таймауты и тесты с ReDoS-пэйлоадами.
Контекст
Команда хотела гибкую валидацию юзернейма и позаимствовала классический регексп «\\w+\\.?» в цикле. В итоге даже обычный пользователь с длинным ником может положить регистрацию. Нет лимитов размера запроса, нет circuit breaker.
- Проверь, какие ограничения стоят на поле
username. - Подумай о миграции на
Pattern.compileс белым списком,@Size(max = 64), rate limiting. - Добавь тесты: `MockMvc` + payload из 10k «a» — endpoint должен отвечать 400 за миллисекунды, а не зависать.
Сниппет
Code Review
Референс-исправление
Используй безопасные валидаторы и лимиты. Регексп можно заменить на whitelist с Character.isLetterOrDigit.
Флаг ревью: FLAG{java-redos-signup}
public record SignupRequest(
@Size(min = 3, max = 40)
@Pattern(regexp = "^[A-Za-z0-9_.-]+$", message = "username: letters, digits, _.-")
String username,
@Email
@Size(max = 120)
String email
) {}
Добавь rate limiter, `spring.mvc.async.request-timeout`, тесты с ReDoS-пэйлоадами и мониторинг задержек.
Проверка флага
После ревью зафиксируй флаг, чтобы дашборд засчитал лабораторию.