CVE-2026-97468

Weak Authentication
Affects
Apache CXF
in
Apache CXF
No items found.
Versions
<3.6.13, >=4.0.0 <4.1.9, >=4.2.0 <4.2.4

Patch Available.

Exclamation circle icon
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.

A weak authentication vulnerability (CVE-2026-97468) has been identified in the STSTokenValidator and the Security Token Service (STS) of Apache CXF, which allows attackers to authenticate as another user by presenting a crafted security token whose hash collides with a previously validated, cached token. Through STS token validation or renewal, the attacker can also obtain STS-signed tokens for that identity.

Per OWASP: When an attacker is able to trick a system into recognizing an invalid or incorrect user as legitimate, this vulnerability is present.

This issue affects multiple versions of Apache CXF.

Details

Module Info

Vulnerability Info

This High-severity vulnerability is found in the org.apache.cxf:cxf-rt-ws-security package in multiple versions of Apache CXF. To avoid repeating expensive work, the STSTokenValidator and the STS token validators cache tokens they have already validated. The cache key is a non-cryptographic 32-bit Java hash of the presented token: Arrays.hashCode over a SAML Assertion's signature value, or hashCode() of a UsernameToken, BinarySecurityToken or SecurityContextToken. A later request whose token produces the same hash is treated as already validated.

In STSTokenValidator.validateWithSTS, a cache hit returns the cached transformed token and the credential is accepted without calling the STS:

int hash = 0;
if (credential.getSamlAssertion() != null) {
    SamlAssertionWrapper assertion = credential.getSamlAssertion();
    byte[] signatureValue = assertion.getSignatureValue();
    if (signatureValue != null && signatureValue.length > 0) {
        hash = Arrays.hashCode(signatureValue);
    }
    tokenElement = credential.getSamlAssertion().getElement();
} else if (credential.getUsernametoken() != null) {
    tokenElement = credential.getUsernametoken().getElement();
    hash = credential.getUsernametoken().hashCode();
}
...
if (ts != null && hash != 0) {
    SecurityToken transformedToken = getTransformedToken(ts, hash);
    if (transformedToken != null && !transformedToken.isExpired()) {
        SamlAssertionWrapper assertion = new SamlAssertionWrapper(transformedToken.getToken());
        credential.setPrincipal(new SAMLTokenPrincipalImpl(assertion));
        credential.setTransformedToken(assertion);
        return credential;
    }
}

The lookup in getTransformedToken only checks that the stored hash equals the computed one:

SecurityToken recoveredToken = ts.getToken(Integer.toString(hash));
if (recoveredToken != null && recoveredToken.getTokenHash() == hash) {

The STS UsernameTokenValidator follows the same pattern. When the token store holds an entry under ut.hashCode(), the password check in validator.validate is skipped entirely:

int hash = ut.hashCode();
SecurityToken secToken = null;
if (tokenParameters.getTokenStore() != null) {
    secToken = tokenParameters.getTokenStore().getToken(Integer.toString(hash));
    if (secToken != null && (secToken.getTokenHash() != hash || secToken.isExpired())) {
        secToken = null;
    }
}

The SAML token validator, the SAML token renewer and the STS cache utilities key their entries on Arrays.hashCode of the signature value in the same way. Because a 32-bit hash can be collided by an attacker who controls the token contents, a crafted UsernameToken or self-signed SAML Assertion that hashes to the same value as a cached token from a legitimate user is accepted without password validation, signature trust verification or a call to the STS. The attacker is then authenticated as that user and can use STS validation or renewal to obtain STS-signed tokens for the same identity.

Mitigation

Only recent versions of Apache CXF are community-supported. 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

  • MopMonk-AI (finder)
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
High
ID
CVE-2026-97468
PROJECT Affected
Apache CXF
Versions Affected
<3.6.13, >=4.0.0 <4.1.9, >=4.2.0 <4.2.4
NES Versions Affected
Published date
October 9, 2026
≈ Fix date
October 14, 2026
Category
Weak Authentication
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Apache CXF
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.