CVE-2026-68481
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Apache CXF is an open-source services framework, maintained by the Apache Software Foundation, for building and consuming web services in Java. It implements the JAX-WS and JAX-RS APIs and supports SOAP, the WS-* standards, RESTful HTTP, and OAuth 2.0 over transports such as HTTP and JMS. Its modules are published as Maven artifacts under org.apache.cxf.
An Authorization Bypass vulnerability (CVE-2026-68481) has been identified in the DefaultEncryptingOAuthDataProvider class of the Apache CXF OAuth 2.0 module (cxf-rt-rs-security-oauth2), which allows attackers holding a revoked access token or refresh token to keep using it to access protected resources and obtain new access tokens, while token introspection continues to report the revoked token as active.
Per OWASP: Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification, or destruction of all data or performing a business function outside the user's limits.
This issue affects all versions prior to 3.6.12, 4.0.0 through 4.1.7, and 4.2.0 through 4.2.2 of Apache CXF, in deployments that use DefaultEncryptingOAuthDataProvider, or its subclass DefaultEncryptingCodeDataProvider, as the OAuth 2.0 data provider.
Details
Module Info
- Product: Apache CXF
- Affected packages:
org.apache.cxf:cxf-rt-rs-security-oauth2 - Affected versions: <3.6.12, >=4.0.0 <4.1.8, >=4.2.0 <4.2.3
- GitHub repository: https://github.com/apache/cxf
- Published packages: https://central.sonatype.com/artifact/org.apache.cxf/cxf-rt-rs-security-oauth2
- Package manager: Maven
- Fixed in:
- OSS Apache CXF 3.6.12, 4.1.8, 4.2.3
- NES for Apache CXF v3.5.13, v3.4.12
Vulnerability Info
This High-severity vulnerability is found in the org.apache.cxf:cxf-rt-rs-security-oauth2 package in all versions prior to 3.6.12, 4.0.0 through 4.1.7, and 4.2.0 through 4.2.2 of Apache CXF.
DefaultEncryptingOAuthDataProvider is a stateless-style OAuth 2.0 data provider: instead of storing token state server-side, the token key handed to the client is the encrypted, serialized token itself. The provider only keeps the set of currently valid encrypted keys in two in-memory sets, tokens and refreshTokens. Revoking a token, whether through the RFC 7009 TokenRevocationService, a refresh-token rotation, or client removal, simply removes the key from the matching set:
public class DefaultEncryptingOAuthDataProvider extends AbstractOAuthDataProvider {
protected SecretKey key;
private Set<String> tokens = Collections.synchronizedSet(new HashSet<>());
private Set<String> refreshTokens = Collections.synchronizedSet(new HashSet<>());
// ...
@Override
protected void doRevokeAccessToken(ServerAccessToken at) {
tokens.remove(at.getTokenKey());
}
// ...
@Override
protected void doRevokeRefreshToken(RefreshToken rt) {
refreshTokens.remove(rt.getTokenKey());
}
// ...
}
However, the lookup methods never consult those sets. Any token string that still decrypts with the provider's secret key is turned back into a fully populated token object, including tokens that were revoked:
@Override
public ServerAccessToken getAccessToken(String accessToken) throws OAuthServiceException {
try {
return ModelEncryptionSupport.decryptAccessToken(this, accessToken, key);
} catch (SecurityException ex) {
throw new OAuthServiceException(OAuthConstants.ACCESS_DENIED, ex);
}
}
// ...
@Override
protected RefreshToken getRefreshToken(String refreshTokenKey) {
try {
return ModelEncryptionSupport.decryptRefreshToken(this, refreshTokenKey, key);
} catch (SecurityException ex) {
throw new OAuthServiceException(OAuthConstants.ACCESS_DENIED, ex);
}
}
getAccessToken is what the CXF access token validators and TokenIntrospectionService call for every bearer token presented to the server. Because it returns a non-null, unexpired token for a revoked key, introspection answers active: true and protected resources keep accepting the token until its natural expiry. getRefreshToken is used by the refresh token grant, so a revoked refresh token can still be exchanged for fresh access tokens. An attacker who has obtained a token that the user or administrator has since revoked (for example after a logout, a suspected leak, or a client deregistration) retains the access that revocation was meant to remove, contrary to the RFC 7009 requirement that the authorization server invalidate the token and the RFC 7662 requirement that introspection of a revoked token return active: false.
Mitigation
Only recent versions of Apache CXF receive community support. Older lines are End-of-Life and will not receive public updates to address this issue.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported Apache CXF release line (3.6.x or later) that contains the fix.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
Credits
- Guanping Zhang (finder)