Spring WebFlux - CVE-2023-34034 Anlatım Konusu
Spring Security'nin yeni sürümleri, kırık bir erişim kontrolü zafiyeti için bir düzeltme içermektedir - CVE-2023-34034 - bu, Kritik NVD şiddeti (CVSS 9.8) ve Yayının sürdürücüleri tarafından yüksek şiddetle verilmiştir.
Spring WebFlux Nedir?
Spring Framework, işletme düzeyinde Java uygulamalarının geliştirilmesi için altyapı desteği sağlayan yaygın olarak kullanılan bir Java tabanlı uygulama çatısıdır.
Spring Security, güçlü bir kimlik doğrulama ve erişim kontrol çerçevesidir ve Spring tabanlı uygulamaların güvenliğinde endüstri standardıdır. Hem kimlik doğrulaması hem de yetkilendirme sağlar ve özel gereksinimleri karşılamak için kolayca genişletilebilir.
Spring WebFlux, geleneksel Spring Web MVC çerçevesine alternatif olarak Spring 5'te tanıtılmıştır.
Temelinde, Spring WebFlux, asenkron, bloklamayan ve reaktif programlama paradigmalarını ele almak üzere tasarlanmıştır. Geliştiricilere ölçeklenebilir, duyarlı ve dirençli uygulamalar oluşturabilmeleri için reaktif programlama modeli sunar. Geleneksel talep başına iş parçacığı yaklaşımı yerine, WebFlux, çok sayıda isteği birkaç iş parçacığıyla eş zamanlı olarak işlemeyi sağlayan reaktif akış API'sini kullanır.
Zafiyet Arka Planı
İşte kaynak koduna dair derinlemesine analizimiz, 7813a9b düzeltme taahhüdü ile başlayarak.
web/src/main/java/org/springframework/security/web/server/util/matcher/PathPatternParserServerWebExchangeMatcher.java dosyasındaki değişiklikler ilginç görünüyor:
Düzeltmeden önce, yan yana farka bakıldığında, PathPatternParserServerWebExchangeMatcher sınıfının PathPatternParser sınıfında uygulanan parse() yöntemini kullandığını görebiliriz.
Düzeltme taahhüdü, PathPatternParserServerWebExchangeMatcher sınıfında uygulanan yeni bir parse() işlevi tanıtır ve bu işlev, PathPatternParser'ın initFullPathPattern() ile parse() yöntemini genişletir.
Kaynak koduna bakıldığında, yardımcı işlevin bir dizesinin başına bir ileri eğik çizgi eklediğini görebiliriz, ancak zaten varsa eklemiyor.
Kod:
/**
* 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);
}
Commit'e daha fazla bakıldığında, yeni tanıtılan testle birlikte bu değerlendirme doğrulanır:
Kod:
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();
}
}
Test, yol kullanıcı/** için bir ayrıştırıcı oluşturur ve yolun /user/test ile eşleşip eşleşmediğini kontrol eder. Bu taahhütte tanıtılan önceki eğik çizgi eklenmeden, yollar eşleşmezdi. initFullPathPattern(), eşleşmeleri sağlar.
Bunların hepsi ** yoluna nasıl ilişkilendirilir?
Aşağıdaki özel filtre ** içerir. Diyelim ki sitenizdeki tüm sayfalara admin sayfaları dışında erişilebilir yapmak istiyorsunuz, aşağıdaki kuralı ayarlamış olabilirsiniz:
Bunların hepsi ** yoluna nasıl ilişkilendirilir?
Aşağıdaki özel filtre ** içerir. Diyelim ki sitenizdeki tüm sayfalara admin sayfaları dışında erişilebilir yapmak istiyorsunuz, aşağıdaki kuralı ayarlamış olabilirsiniz:
Kod:
.authorizeExchange()
.pathMatchers("admin/**")
.hasRole(Roles.ADMIN)
.and()
.authorizeExchange()
.anyExchange()
.permitAll();
Mantıklı bir şekilde düşünerek, şimdi admin/ altındaki her sayfaya yalnızca yöneticilerin erişebileceğini düşündük.
Düzeltmeden önce, bu kural herhangi bir admin/ URL'sine eşleşmeyecek, çünkü önceki / eksik ve admin/ altındaki tüm web sayfaları herkes tarafından erişilebilir olacaktı.
Basit bir Spring WebFlux uygulaması oluşturduk, bu uygulama Kullanıcı ve Yönetici rollerini içerir ve Spring Security'nin savunmasız bir sürümünü kullanır.
Bu uygulamada, bir giriş sayfası ve bir yönetici uç noktası bulunmaktadır.
Kurallar şu şekilde belirlenmiştir:
Düzeltmeden önce, bu kural herhangi bir admin/ URL'sine eşleşmeyecek, çünkü önceki / eksik ve admin/ altındaki tüm web sayfaları herkes tarafından erişilebilir olacaktı.
Basit bir Spring WebFlux uygulaması oluşturduk, bu uygulama Kullanıcı ve Yönetici rollerini içerir ve Spring Security'nin savunmasız bir sürümünü kullanır.
Bu uygulamada, bir giriş sayfası ve bir yönetici uç noktası bulunmaktadır.
Kurallar şu şekilde belirlenmiştir:
Kod:
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();
.anyExchange().permitAll(), .pathMatchers("admin/**").hasRole(Roles.ADMIN) talimatı tarafından belirtildiği gibi, tüm sayfaların erişilebilir olmasına izin verir, yalnızca yönetici sayfaları hariç.
Zafiyetten dolayı, "admin/**" kuralı herhangi bir URL'ye eşleşmeyecek, çünkü başında bir eğik çizgi eksik. Örneğin, bir saldırgan aslında bir yönetici olmasa bile "admin/supershell" URL'sine serbestçe erişebilir. Kanıtımız, bu sayfaların hala erişilebilir olduğunu göstermektedir.
Bir saldırgan, bu zafiyetli şekilde "güvenceye alınan" bir uç noktanın farkında ise, herhangi bir kimlik doğrulaması olmaksızın ayrıcalıklı uç noktalara erişmek oldukça kolaydır.
CVE-2023-34034'ten Kim Etkilenir
Web uygulaması Spring WebFlux çerçevesini kullanıyorsa (daha eski bir "Spring MVC" çerçevesini kullanan uygulamalar etkilenmez).
Web uygulaması, savunmasız bir Spring Security sürümünü kullanıyorsa. Örneğin, 5.6.0.
Web uygulaması, Spring Security erişim kurallarını ayarlamak için URL yol filtreleme kullanıyorsa. URL yol kalıbı, bir ileri eğik çizgi karakteri (/) ile başlamıyorsa. Örneğin, pathMatchers("admin/supershell"). Bu, bu örnekte tek bir sayfayı etkiler, yani admin/supershell sayfasını.
Ayrıca, URL yolunda birden çok bölüm joker karakteri () bulunuyorsa, bu zafiyetin şiddetini artırır. Örneğin, pathMatchers("admin/"). Bu, URL yolunun altındaki tüm sayfaları etkiler, bu örnekte, admin sayfasının altındaki her şeyi.
Çözüm
Spring Security sürümünüzü aşağıdakilerden birine yükseltmek kesinlikle önerilir:
6.1.2+
6.0.5+
5.8.5+
5.7.10+
5.6.12+
Yukarıdaki, Spring Framework sürümlerini gerektirir:
6.0.11+
5.3.29+
5.2.25+
Alternatif olarak, Spring Security'de kullanılan herhangi bir URL filtresine başında bir ileri eğik çizgi / ekleyin.
Örneğin, şunu değiştirin:
pathMatchers("admin/**")
şununla:
pathMatchers("/admin/**")
Kaynaklarım jfrog
Zafiyetten dolayı, "admin/**" kuralı herhangi bir URL'ye eşleşmeyecek, çünkü başında bir eğik çizgi eksik. Örneğin, bir saldırgan aslında bir yönetici olmasa bile "admin/supershell" URL'sine serbestçe erişebilir. Kanıtımız, bu sayfaların hala erişilebilir olduğunu göstermektedir.
Bir saldırgan, bu zafiyetli şekilde "güvenceye alınan" bir uç noktanın farkında ise, herhangi bir kimlik doğrulaması olmaksızın ayrıcalıklı uç noktalara erişmek oldukça kolaydır.
CVE-2023-34034'ten Kim Etkilenir
Web uygulaması Spring WebFlux çerçevesini kullanıyorsa (daha eski bir "Spring MVC" çerçevesini kullanan uygulamalar etkilenmez).
Web uygulaması, savunmasız bir Spring Security sürümünü kullanıyorsa. Örneğin, 5.6.0.
Web uygulaması, Spring Security erişim kurallarını ayarlamak için URL yol filtreleme kullanıyorsa. URL yol kalıbı, bir ileri eğik çizgi karakteri (/) ile başlamıyorsa. Örneğin, pathMatchers("admin/supershell"). Bu, bu örnekte tek bir sayfayı etkiler, yani admin/supershell sayfasını.
Ayrıca, URL yolunda birden çok bölüm joker karakteri () bulunuyorsa, bu zafiyetin şiddetini artırır. Örneğin, pathMatchers("admin/"). Bu, URL yolunun altındaki tüm sayfaları etkiler, bu örnekte, admin sayfasının altındaki her şeyi.
Çözüm
Spring Security sürümünüzü aşağıdakilerden birine yükseltmek kesinlikle önerilir:
6.1.2+
6.0.5+
5.8.5+
5.7.10+
5.6.12+
Yukarıdaki, Spring Framework sürümlerini gerektirir:
6.0.11+
5.3.29+
5.2.25+
Alternatif olarak, Spring Security'de kullanılan herhangi bir URL filtresine başında bir ileri eğik çizgi / ekleyin.
Örneğin, şunu değiştirin:
pathMatchers("admin/**")
şununla:
pathMatchers("/admin/**")
Kaynaklarım jfrog


