Недавно выпущенные версии Spring Security содержат исправление уязвимости неработающего контроля доступа — CVE-2023-34034, — которой сопровождающие Spring присвоили критическую серьезность NVD (CVSS 9.8) и высокую степень серьезности.
Учитывая серьезное потенциальное влияние уязвимости на приложения Spring WebFlux (которые используют Spring Security для аутентификации и контроля доступа), ее высокую популярность в отрасли и отсутствие общедоступной информации о деталях эксплуатации, это исправление безопасности побудило группу JFrog Security Research исследовать уязвимость.
В этой записи блога содержатся сведения об этой уязвимости, о том, кому она подвержена, а также о проверке концепции, демонстрирующей, в каких случаях уязвимость может быть вызвана обходом проверки подлинности.
Что такое Spring WebFlux?
Spring Framework — это широко используемая среда приложений на основе Java, которая обеспечивает поддержку инфраструктуры для разработки Java-приложений корпоративного уровня.Spring Security — это мощная платформа аутентификации и управления доступом, а также отраслевой стандарт защиты приложений на основе Spring. Он обеспечивает как аутентификацию, так и авторизацию и может быть легко расширен в соответствии с пользовательскими требованиями.
Spring WebFlux был представлен в Spring 5 как альтернатива традиционному фреймворку Spring Web MVC для реактивного программирования.
По своей сути Spring WebFlux предназначен для работы с парадигмами асинхронного, неблокирующего и реактивного программирования. Он предоставляет модель реактивного программирования, которая позволяет разработчикам создавать масштабируемые, отзывчивые и устойчивые приложения. Вместо традиционного подхода «поток на запрос» WebFlux использует API реактивных потоков, который позволяет обрабатывать несколько запросов одновременно с небольшим количеством потоков.
Предыстория уязвимости
18 июля 2023 года Spring Security выпустила новые версии с этой рекомендацией по безопасности, которая привлекла наше внимание, поскольку это была уязвимость обхода фильтра. При поиске в репозитории Spring на GitHub это фиксация исправления.Подробные сведения об уязвимости
Описание в рекомендациях Spring очень абстрактно и не содержит подробностей о том, какие именно варианты использования Spring затронуты этой проблемой.Вот наш глубокий анализ исходного кода, начиная с фикс-коммита — 7813a9b.
Изменения в файле web/web/src/main/java/org/springframework/security/web/server/util/matcher/PathPatternParserServerWebExchangeMatcher.java кажутся интересными:
Глядя на параллельную разницу, до исправления мы видим, что класс PathPatternParserServerWebExchangeMatcher использовал метод parse() реализованный в классе PathPatternParser.
Фиксация вводит новую функцию parse(), реализованную в самом классе PathPatternParserServerWebExchangeMatcher, которая расширяет метод parse()) PathPatternParser с initFullPathPattern() parse().
Глядя на исходный код, мы видим, что служебная функция добавляет косую черту в начале строки, только если ее еще нет.
C#:
/**
* Prepare the given pattern for use in matching to full URL paths.
* By default, prepend a leading slash if needed for non-empty patterns.
* @param pattern the pattern to initialize
* @return the updated pattern
* @since 5.2.25
*/
public String initFullPathPattern(String pattern) {
return (StringUtils.hasLength(pattern) && !pattern.startsWith("/") ? "/" + pattern : pattern);
}
C#:
class PathPatternParserServerWebExchangeMatcherTests {
@Test
void matchesWhenConfiguredWithNoTrailingSlashAndPathContainsSlashThenMatches() {
PathPatternParserServerWebExchangeMatcher matcher = new PathPatternParserServerWebExchangeMatcher("user/**");
MockServerHttpRequest request = MockServerHttpRequest.get("/user/test").build();
assertThat(matcher.matches(MockServerWebExchange.from(request)).block().isMatch()).isTrue();
}
}
Как все это связано с ** путем?
Следующий пользовательский фильтр содержит **. Допустим, вы хотите сделать доступными все страницы вашего сайта, кроме страниц администратора, возможно, вы установили следующее правило:
HTTP:
.authorizeExchange()
.pathMatchers("admin/**")
.hasRole(Roles.ADMIN)
.and()
.authorizeExchange()
.anyExchange()
.permitAll();
Думая (разумно), что теперь каждая страница под admin/ может быть доступна только администраторам.
До исправления это правило не соответствовало ни одному admin//, так как в нем отсутствует предыдущий / и все веб-страницы в admin/ будут доступны любому.
Доказательство концепции
Мы создали простое приложение Spring WebFlux, которое включает роли пользователя и администратора и использует уязвимую версию Spring Security.В этом приложении есть страница входа и конечная точка администратора.
Правила установлены следующим образом:
HTTP:
// disable CSRF
.csrf().disable()
// add AuthenticationWebFilter and set the handler
.formLogin()
.authenticationSuccessHandler(new WebFilterChainServerAuthenticationSuccessHandler())
.authenticationFailureHandler(((webFilterExchange, exception) -> Mono.error(exception)))
.and()
.authorizeExchange()
.pathMatchers("admin/**")
.hasRole(Roles.ADMIN)
.and()
.authorizeExchange()
.anyExchange()
.permitAll();
return http.build();
Из-за уязвимости правило “admin/**” не будет соответствовать ни одному URL-адресу, так как в начале отсутствует косая черта. Например, злоумышленник сможет получить свободный доступ к URL-адресу “/admin/supershell” фактически не будучи администратором. Наш PoC показывает, как эти страницы будут по-прежнему доступны.
Если злоумышленнику известно о конечной точке, которая была «защищена» таким уязвимым способом, доступ к привилегированным конечным точкам без проверки подлинности является тривиальным.
Кто подвержен уязвимости CVE-2023-34034
Данная уязвимость применяется в следующих случаях:- Веб-приложение использует платформу Spring WebFlux (приложения, использующие более старую платформу Spring MVC, не затрагиваются).
- Веб-приложение использует уязвимую версию Spring Security. Например, 5.6.0.
- Веб-приложение использует фильтрацию URL-путей для настройки правил доступа Spring Security. Шаблон пути URL-адреса НЕ начинается с символа прямой косой черты (/). pathMatchers("admin/supershell"). Это повлияет на одну страницу, в данном примере на страницу admin/supershell.
Кроме того, если URL-путь содержит многосегментный подстановочный знак (**), это увеличивает серьезность уязвимости. pathMatchers("admin/**"). Это повлияет на все страницы под URL-путем, в данном примере на все, что находится под страницей admin.
Исправление
Настоятельно рекомендуется обновить версию Spring Security до одной из следующих версий:- 6.1.2+
- 6.0.5+
- 5.8.5+
- 5.7.10+
- 5.6.12+
- 6.0.11+
- 5.3.29+
- 5.2.25+
Например, замените –
pathMatchers("admin/**")
с–
pathMatchers("/admin/**")
Уязвима ли платформа JFrog для CVE-2023-34034?
Проведя внутренний анализ, мы можем подтвердить, что платформа JFrog не уязвима для CVE-2023-34034 Spring.Контекстный анализ с помощью JFrog Advanced Security
Функция контекстного анализа, включенная в набор возможностей JFrog Advanced Security для JFrog Xray, позволяет пользователям автоматически определять, применимы ли эти уязвимости в кодовой базе пользователя. Этот процесс включает в себя запуск автоматических контекстных сканеров образа контейнера для определения достижимых путей и параметров конфигурации для анализируемых уязвимостей. Xray автоматически проверяет CVE, которые имеют предварительные условия эксплуатации, и предоставляет отчет о контекстном анализе, который определяет, какие уязвимости применимы или нет. Это избавляет разработчиков от напрасной траты времени и усилий.- Экономьте время разработчиков, устраняя только те уязвимости, которые применимы
- Анализируйте готовый код (двоичный код) так же, как и злоумышленник
- Узнайте, какие CVE можно использовать и их потенциальное влияние
- Тестирование уязвимости в контексте полного артефакта, сборки или пакета выпуска
- Включение действий и исправлений в контексте артефакта, сборки или пакета выпуска