CVE-2025-41248
Description
The Spring Security annotation detection mechanism may not correctly resolve annotations on methods within type hierarchies with a parameterized super type with unbounded generics. This can be an issue when using @PreAuthorize and other method security annotations, resulting in an authorization bypass.
Your application may be affected by this if you are using Spring Security's @EnableMethodSecurity feature.
You are not affected by this if you are not using @EnableMethodSecurity or if you do not use security annotations on methods in generic superclasses or generic interfaces.
This CVE is published in conjunction with CVE-2025-41249 https://spring.io/security/cve-2025-41249 .
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.springframework.security:spring-security-coreMaven | >= 6.4.0, < 6.4.10 | 6.4.10 |
org.springframework.security:spring-security-coreMaven | >= 6.5.0, < 6.5.4 | 6.5.4 |
Affected products
1- Range: >= 6.5.0, < 6.5.4
Patches
2d0f93fa6d833Merge branch '6.4.x' into 6.5.x
2 files changed · +33 −1
core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java+1 −1 modified@@ -305,7 +305,7 @@ private static boolean hasSameGenericTypeParameters(Method rootMethod, Method ca } for (int i = 0; i < rootParameterTypes.length; i++) { Class<?> resolvedParameterType = ResolvableType.forMethodParameter(candidateMethod, i, sourceDeclaringClass) - .resolve(); + .toClass(); if (rootParameterTypes[i] != resolvedParameterType) { return false; }
core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java+32 −0 modified@@ -28,6 +28,7 @@ import org.springframework.core.annotation.AnnotationConfigurationException; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.util.ClassUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -326,6 +327,14 @@ void scanParameterAnnotationWhenPresentInParentAndInterfaceThenException() throw .isThrownBy(() -> this.parameterScanner.scan(parameter)); } + // gh-17898 + @Test + void scanWhenAnnotationOnParameterizedUndeclaredMethodAndThenLocates() throws Exception { + Method method = ClassUtils.getMethod(GenericInterfaceImpl.class, "processOneAndTwo", Long.class, Object.class); + PreAuthorize pre = this.scanner.scan(method, method.getDeclaringClass()); + assertThat(pre).isNotNull(); + } + interface UserService { void add(@CustomParameterAnnotation("one") String user); @@ -764,4 +773,27 @@ <S extends Number> S getExtByClass(Class<S> clazz, Long l) { } + interface GenericInterface<A, B> { + + @PreAuthorize("hasAuthority('thirtythree')") + void processOneAndTwo(A value1, B value2); + + } + + abstract static class GenericAbstractSuperclass<C> implements GenericInterface<Long, C> { + + @Override + public void processOneAndTwo(Long value1, C value2) { + } + + } + + static class GenericInterfaceImpl extends GenericAbstractSuperclass<String> { + + // The compiler does not require us to declare a concrete + // processOneAndTwo(Long, String) method, and we intentionally + // do not declare one here. + + } + }
e5694ac7b5e4Fallback to Object When Determining Overridden Methods
2 files changed · +33 −1
core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java+1 −1 modified@@ -252,7 +252,7 @@ private static boolean hasSameGenericTypeParameters(Method rootMethod, Method ca } for (int i = 0; i < rootParameterTypes.length; i++) { Class<?> resolvedParameterType = ResolvableType.forMethodParameter(candidateMethod, i, sourceDeclaringClass) - .resolve(); + .toClass(); if (rootParameterTypes[i] != resolvedParameterType) { return false; }
core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java+32 −0 modified@@ -22,6 +22,7 @@ import org.springframework.core.annotation.AnnotationConfigurationException; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.util.ClassUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -275,6 +276,14 @@ void scanWhenAnnotationOnParameterizedMethodThenLocates() throws Exception { assertThat(pre).isNotNull(); } + // gh-17898 + @Test + void scanWhenAnnotationOnParameterizedUndeclaredMethodAndThenLocates() throws Exception { + Method method = ClassUtils.getMethod(GenericInterfaceImpl.class, "processOneAndTwo", Long.class, Object.class); + PreAuthorize pre = this.scanner.scan(method, method.getDeclaringClass()); + assertThat(pre).isNotNull(); + } + @PreAuthorize("one") private interface AnnotationOnInterface { @@ -637,4 +646,27 @@ <S extends Number> S getExtByClass(Class<S> clazz, Long l) { } + interface GenericInterface<A, B> { + + @PreAuthorize("hasAuthority('thirtythree')") + void processOneAndTwo(A value1, B value2); + + } + + abstract static class GenericAbstractSuperclass<C> implements GenericInterface<Long, C> { + + @Override + public void processOneAndTwo(Long value1, C value2) { + } + + } + + static class GenericInterfaceImpl extends GenericAbstractSuperclass<String> { + + // The compiler does not require us to declare a concrete + // processOneAndTwo(Long, String) method, and we intentionally + // do not declare one here. + + } + }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-8v5q-rhf3-jphmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-41248ghsaADVISORY
- github.com/spring-projects/spring-security/commit/d0f93fa6d8338149943ae640c53db07de827867fghsaWEB
- github.com/spring-projects/spring-security/commit/e5694ac7b5e4394b920c6cab48b7bfbd871f84bdghsaWEB
- github.com/spring-projects/spring-security/issues/17898ghsaWEB
- github.com/spring-projects/spring-security/issues/17899ghsaWEB
- github.com/spring-projects/spring-security/releases/tag/6.4.10ghsaWEB
- github.com/spring-projects/spring-security/releases/tag/6.5.4ghsaWEB
- spring.io/security/cve-2025-41248nvdWEB
News mentions
0No linked articles in our index yet.