CVE-2026-40995
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Web Services (Spring WS) is a product of the Spring community focused on creating document-driven SOAP web services, facilitating contract-first development and integrating with Spring Security for securing message exchanges.
A medium-severity vulnerability (CVE-2026-40995) has been identified in the X.509 certificate authentication support of the spring-ws-security module. The X509AuthenticationProvider issued a fully authenticated token whenever a presented client certificate mapped to a known user, without applying Spring Security's standard account lifecycle checks. As a result, accounts that are disabled, locked, expired, or have expired credentials could still authenticate when mutual TLS or certificate-based SOAP authentication was in use.
Per OWASP, this is a form of broken access control: access control enforces policy such that users cannot act outside of their intended permissions, and failures typically lead to unauthorized information disclosure, modification, or destruction of data, or performing a business function outside the user's limits. In this case, users whose accounts were administratively deactivated retained full access as long as they still held a valid client certificate.
This issue affects >=2.4.0 <=2.4.7, >=3.1.0 <=3.1.8, >=4.0.0 <=4.0.18, >=4.1.0 <=4.1.3, and >=5.0.0 <=5.0.1 of Spring Web Services.
Details
Module Info
- Product: Spring Web Services
- Affected packages: spring-ws-security
- Affected versions: >=2.4.0 <=2.4.7, >=3.1.0 <=3.1.8, >=4.0.0 <=4.0.18, >=4.1.0 <=4.1.3, >=5.0.0 <=5.0.1
- GitHub repository: https://github.com/spring-projects/spring-ws
- Published packages: https://central.sonatype.com/artifact/org.springframework.ws/spring-ws-security
- Package manager: Maven
- Fixed in:
- NES for Spring Web Services 2.4.x, 3.1.x, 4.0.x
- Spring Web Services 5.0.2, 4.1.4 (OSS)
Vulnerability Info
Spring WS integrates with Spring Security to authenticate SOAP clients by their X.509 client certificate, typically presented over mutual TLS. The provider class X509AuthenticationProvider resolves the certificate to a UserDetails record, either from an X509UserCache or by calling the configured X509AuthoritiesPopulator, and then issues an authenticated X509AuthenticationToken:
UserDetails user = this.userCache.getUserFromCache(clientCertificate);
if (user == null) {
if (logger.isDebugEnabled()) {
logger.debug("Authenticating with certificate " + clientCertificate);
}
user = this.x509AuthoritiesPopulator.getUserDetails(clientCertificate);
this.userCache.putUserInCache(clientCertificate, user);
}
X509AuthenticationToken result = new X509AuthenticationToken(user, clientCertificate, user.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
At no point does this flow consult the account state flags on the resolved UserDetails (isEnabled(), isAccountNonLocked(), isAccountNonExpired(), isCredentialsNonExpired()). Spring Security's own username/password providers run these checks through an AccountStatusUserDetailsChecker before completing authentication, so an account that an administrator has disabled or locked is rejected with the appropriate exception. The Spring WS X.509 path skipped that step entirely, on both the cache-hit path and the fresh-lookup path, so a deactivated account holding a valid client certificate could continue to authenticate and invoke secured SOAP services.
Exploitation requires that certificate-based authentication is wired through the Spring WS X.509 integration with Spring Security, and that user records exist in a non-active security state that should not authenticate. A typical scenario is a terminated or suspended user whose account was disabled but whose client certificate has not yet been revoked at the TLS layer.
The remediation applies the same UserDetailsChecker strategy used by Spring Security's AbstractUserDetailsAuthenticationProvider: the provider now defaults to an AccountStatusUserDetailsChecker that validates the account state of every resolved user, including cached entries, before any token is issued, and a custom checker can be supplied via setAccountStatusUserDetailsChecker.
Mitigation
Only the 4.1.x and 5.0.x lines of Spring Web Services currently receive open-source community support and updates. Older lines, including 2.x, 3.x, and 4.0.x, have no publicly available fixes for this vulnerability.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Web Services (5.0.2 or 4.1.4, or later).
- Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Spring Web Services.