CVE-2026-50634
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 Signature Forgery vulnerability (CVE-2026-50634) has been identified in the JWS JSON filters of Apache CXF (JwsJsonContainerRequestFilter and JwsJsonClientResponseFilter), which allows attackers to have CXF apply Content-Type and protected HTTP header metadata taken from a signature entry that was never verified. An attacker can place an unsigned or invalidly signed entry first in a JWS JSON message, followed by an entry that verifies, and CXF will trust the metadata of the first entry as if it had been authenticated.
Per OWASP: Software and data integrity failures relate to code and infrastructure that does not protect against integrity violations.
This issue affects versions 3.0.3 through 3.6.11, all 4.0.x versions, 4.1.x before 4.1.7, and 4.2.x before 4.2.2 of Apache CXF.
Details
Module Info
- Product: Apache CXF
- Affected packages:
org.apache.cxf:cxf-rt-rs-security-jose-jaxrs(published asorg.apache.cxf:cxf-rt-rs-security-josebefore the 3.1.4 module split) - Affected versions: >=3.0.3 <3.6.12, >=4.0.0 <4.1.7, >=4.2.0 <4.2.2
- GitHub repository: https://github.com/apache/cxf
- Published packages: https://central.sonatype.com/artifact/org.apache.cxf/cxf-rt-rs-security-jose-jaxrs
- Package manager: Maven
- Fixed in:
- OSS Apache CXF 4.2.2, 4.1.7, 3.6.12
- NES for Apache CXF v3.4.12 and v3.5.13
Vulnerability Info
This Medium-severity vulnerability is found in the org.apache.cxf:cxf-rt-rs-security-jose-jaxrs package in versions 3.0.3 through 3.6.11, all 4.0.x versions, 4.1.x before 4.1.7, and 4.2.x before 4.2.2 of Apache CXF.
A JWS JSON (General JSON Serialization) message can carry several signature entries over the same payload. CXF's JWS JSON filters accept a message as soon as one entry verifies against the configured verifier. In AbstractJwsJsonReaderProvider, validate() calls verifyAndGetNonValidated(), which succeeds when a single entry verifies and records every other entry as unverified under the "jws.json.remaining.entries" message property:
protected void validate(JwsJsonConsumer c, JwsSignatureVerifier theSigVerifier) throws JwsException {
List<JwsJsonSignatureEntry> remaining =
c.verifyAndGetNonValidated(Collections.singletonList(theSigVerifier), entryProps);
if (!remaining.isEmpty()) {
JAXRSUtils.getCurrentMessage().put("jws.json.remaining.entries", remaining);
}
JAXRSUtils.getCurrentMessage().put(JwsJsonConsumer.class, c);
}
After validation succeeds, JwsJsonContainerRequestFilter ignores which entry actually verified. It always reads the Content-Type and the protected header from the first entry in the message:
byte[] bytes = c.getDecodedJwsPayloadBytes();
context.setEntityStream(new ByteArrayInputStream(bytes));
context.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length));
// the list is guaranteed to be non-empty
JwsJsonSignatureEntry sigEntry = c.getSignatureEntries().get(0);
String ct = JoseUtils.checkContentType(sigEntry.getUnionHeader().getContentType(), getDefaultMediaType());
if (ct != null) {
context.getHeaders().putSingle("Content-Type", ct);
}
if (super.isValidateHttpHeaders()) {
super.validateHttpHeadersIfNeeded(context.getHeaders(), sigEntry.getProtectedHeader());
}
JwsJsonClientResponseFilter has the same c.getSignatureEntries().get(0) lookup for responses. An attacker who holds one validly signed entry, or can replay one, can put an unverified entry with attacker-chosen cty and protected HTTP header values at index 0. The request is still accepted because the second entry verifies. CXF then rewrites the request's Content-Type from the unauthenticated entry, which can steer which JAX-RS entity provider parses the payload. When protected HTTP header validation is enabled, CXF also checks the incoming headers against the attacker's unverified protected header, not the signed one, so the signed-header consistency check can be bypassed.
This vulnerability was introduced in 2014 with Apache CXF 3.0.3.
Mitigation
The 3.5.x line was already End-of-Life when this CVE was published 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
- Mitchell Benjamin from Revamp Studio (finder)