Twelve Flaws in Apache CXF: Seven Skip Checks the Spec Made Mandatory
Apache CXF, the Java layer enterprises use for data exchange, has six new flaws. One lets a single message take over the server. Upgrade to 4.2.3/4.1.8/3.6.12.
Table of contents
Apache CXF, the Java layer enterprises use for data exchange, has six new flaws. One lets a single message take over the server. Upgrade to 4.2.3/4.1.8/3.6.12.
On August 6, 2026, twelve vulnerabilities were disclosed at once in Apache CXF, a Java-based software layer that handles the part where corporate systems exchange data with each other.
The most serious, CVE-2026-66909, can allow an attacker to run arbitrary code on the server by sending a single message. The Apache Software Foundation rated it "important."
The fixed versions are 4.2.3, 4.1.8, and 3.6.12. All twelve issues are resolved in those three releases. As of August 6, there are no reports of exploitation in the wild and no publicly available exploit code.
But the number that matters most here is not the severity rating. It is that seven of the twelve concern the login machinery — and those seven all share one shape: a check the specification declared mandatory was simply not being performed.
Three more share a closely related shape: a setting existed to impose a limit, but no default value was ever placed on it. Only those who configured it were protected. Everyone who did nothing ran without limits, for years.
So ten of the twelve are flaws that work not because an attacker invented something clever, but because a required check was missing. This article walks through each of those gaps.
What Apache CXF is, and why you may be affected without knowing you use it
Apache CXF is a software component that takes over the "exchanging data with the outside" part of a Java business system. Instead of writing all the communication handling yourself, you embed this component and get standardized data exchange.
The format it is best known for is SOAP, which wraps data in XML. It was widely adopted in the early 2000s for system-to-system integration in finance, insurance, telecom, and government. It still sits in the layer connecting a bank's core ledger to its surrounding systems, or handling purchase-order exchange between companies. Few teams choose it for new projects, but systems already running keep running.
That is what makes this disclosure awkward. Apache CXF is often used without the operator ever seeing its name.
| Path | Detail |
|---|---|
| Direct use | Embedded in your own Java app (org.apache.cxf declared in Maven, etc.) |
| Bundled in a product | Red Hat JBoss EAP / Fuse web services subsystem runs on CXF |
| Via integration tools | Apache Camel cxf component, MuleSoft SOAP connectivity |
| Via a development standard | NTT Data's TERASOLUNA and similar guidelines specify CXF for SOAP |
The fourth row is specific to Japan. TERASOLUNA is a development framework NTT Data has offered since 2003, with more than 2,000 cumulative deployments by the company's own count. Its guidelines name Apache CXF as the implementation for SOAP. Business systems built to that standard likely contain CXF.
So even if you are certain you never installed Apache CXF, if you run a Java business system that includes SOAP-based integration, it is worth checking. Methods for inventorying the components you actually ship are covered in our OSS supply chain scanner piece.
The twelve issues at a glance
All twelve were announced on the Apache mailing lists on August 6, in two waves roughly an hour apart. Severity ratings are the project's own.
They split into two very different groups. First, the five concerning data intake.
| CVE | Severity | What can happen | Affected module |
|---|---|---|---|
| CVE-2026-66909 | important | Arbitrary code execution on the server | cxf-rt-transports-jms |
| CVE-2026-65432 | important | Files on the server can be read out | cxf-rt-wsdl |
| CVE-2026-64958 | moderate | Service outage (June fix was incomplete) | cxf-core |
| CVE-2026-54225 | low | Outage via oversized attachment | cxf-core |
| CVE-2026-57819 | low | Outage via huge number of form fields | cxf-rt-frontend-jaxrs |
Then the seven concerning login and permissions. All seven were reported by the same researcher, Guanping Zhang, and all land in the part of Apache CXF that provides login services to other applications (OAuth2 / OpenID Connect).
| CVE | Severity | What was never checked | Affected module |
|---|---|---|---|
| CVE-2026-61466 | moderate | Whether the requested permission scope was allowed | cxf-rt-rs-security-oauth2 |
| CVE-2026-68481 | low | Whether the pass had been revoked | cxf-rt-rs-security-oauth2 |
| CVE-2026-68079 | low | Whether the voucher had already been used | cxf-rt-rs-security-oauth2 |
| CVE-2026-57818 | low | Same, when several requests arrive at once | cxf-rt-rs-security-oauth2 |
| CVE-2026-63687 | low | Whether the anti-theft passphrase was substituted | cxf-rt-rs-security-oauth2 |
| CVE-2026-57817 | low | Whether the voucher was genuine (the c_hash check) | cxf-rt-rs-security-sso-oidc |
| CVE-2026-65583 | low | The ID's issuer, audience and expiry | cxf-rt-rs-security-sso-oidc |
The third column is headed "what was never checked" because once the seven are lined up, the common thread shows before the symptoms do. None of them is a story about an attacker inventing a new route. Every one is a story about a check that was supposed to happen and did not.
All twelve affect versions below 4.2.3, below 4.1.8, and below 3.6.12. None carried a CVSS score (the 10-point severity scale) as of August 6, because the US National Vulnerability Database had not finished its analysis. Scores are expected later.
Who would target this, what they would do, and what it costs you
For the intake-side issues, the realistic threat is an intruder who already has a foothold inside the corporate network. Think of an attacker who came in through a supplier, or who logged in with stolen employee credentials. This is not a flaw reachable straight from the open internet; it matters to someone already positioned to reach internal integration paths.
What would they do? For CVE-2026-66909, the most severe of the twelve, they would drop one crafted message into the system's message inbox. No malware upload is needed. They send a single item shaped like the routine business data the system receives every day. The receiving side opens it the way it always does, and in doing so executes something it was never meant to execute.
What gets lost. For the company running the system, the integration server becomes the attacker's staging ground — and that server is, by design, permitted to talk to other internal systems. From there the blast radius widens. If it connects to core systems, customer and transaction data come into reach. From the end user's side the damage is harder to see, which is precisely the problem: this class of flaw tends to end with "they had been walking around inside for a long time before anyone noticed."
Three of the remaining four intake issues only cause outages and cannot be used for takeover. That is not nothing in an operation where downtime itself is the loss.
The login-side seven attract a different attacker. These are exploited by someone coming in through the front door, following the normal procedure. An application that writes itself extra permissions at registration; a former contractor whose pass was supposedly revoked on departure; a third party reusing a captured voucher. Less an intruder than someone who walks in properly and slips past the checks.
The five found in data intake
CVE-2026-66909: rebuilding whatever arrived, without asking questions
The only one of the twelve that can lead to takeover. Rated "important."
It concerns JMS, a mechanism that lets Java systems hand data to each other through a mailbox rather than a direct connection, so the receiver can pick it up later even if it was down. It is common in enterprise integration.
Messages in that mailbox come in several formats. One of them is ObjectMessage, which takes a chunk of live Java data, flattens it for transport, and restores it on the other end. That restoration step is called deserialization.
The problem is that Apache CXF performed this restoration with no restrictions at all. There was no "only accept this type of data" rule; whatever arrived was rebuilt.
Java's restoration process does not merely assemble data — code runs while it happens. An attacker can craft data so that arbitrary logic executes at the moment of restoration, then simply place it in the mailbox. Whether full code execution succeeds depends on which other libraries happen to be present to serve as stepping stones, but at minimum the service can reliably be knocked over.
This attack shape is an old fixture of the Java world. The same root appears in Fastjson and Apache MINA.
In the fixed versions, ObjectMessage deserialization is disabled by default, with a configuration switch to re-enable it. Reported by n0mi1k.
CVE-2026-65432: the front door was locked, the hallway window was not
Rated "important," and structurally the most instructive of the twelve.
SOAP services are described by a WSDL — an XML document stating what operations a service offers and what data it accepts. Apache CXF reads this blueprint to operate.
XML carries a long-known danger: a document can contain an instruction saying "insert the contents of this file here." Abused, it lets an attacker read out server-side files such as password files. This is called an XXE attack, and the defense is to disable that capability when parsing XML.
Apache CXF did exactly that. The top-level blueprint was read through a hardened path with external entity loading turned off.
But a blueprint is rarely a single sheet. It can reference other files. And the handling of those referenced files was passed to a separate, older component (WSDL4J) — one with no such protection configured.
So the front door was locked while the window down the hallway stayed open. The hardening applied to page one never reached page two. This pattern — protection lapsing at the seam where processing hands off to another component — haunts all software assembled from parts. Also reported by n0mi1k.
CVE-2026-64958: the limit added in June was incomplete
Rated "moderate." Less a new discovery than a redo of the previous fix.
CVE-2026-50645 (severity 7.5), published June 12, 2026, described how there was no cap on the number of attachment headers a message could carry, so flooding a server with them exhausted its processing capacity. That fix introduced a cap of 500 attachments.
This week it emerged that a route remained that slipped past the cap and achieved the same attack. Reported by Markus Vogl of RISE GmbH in Germany.
Organizations that moved to 4.2.2 / 4.1.7 in June have spent two months believing this was handled. It was not fully closed. Incomplete fixes are not unusual here — Apache CXF also saw a follow-up CVE the year after CVE-2025-48913 was found to be insufficiently remediated.
CVE-2026-54225: attachment size had a setting, but no default
Rated "low." Apache CXF has an attachment-max-size option that caps the size of incoming attachments. The capability had been there all along.
The problem was that no default value was ever assigned. Unless an administrator explicitly set one, there was no cap — so a sufficiently large file could exhaust server memory and stop the service.
The fixed versions ship a 50MB default.
CVE-2026-57819: form field count had a setting, but no default either
Rated "low." Same shape as the one above.
A maxFormParameterCount option existed to limit how many fields a submitted web form could carry. It too had no default, so it was unlimited unless configured. A request stuffed with fields takes long enough to process that the service stops responding.
The fixed versions ship a 500-parameter default.
The seven found in login and permissions
One piece of background before the next seven.
Apache CXF includes components that provide the login machinery itself to other applications — the parts you would use to build your own "sign in with our account" service. The mechanisms are called OAuth2 and OpenID Connect (OIDC).
Three things move through that machinery.
The three tickets
- ▸The voucher (authorization code) — handed over for a moment after a successful login, immediately traded for a pass. It may be used only once.
- ▸The pass (access token) — what you receive in exchange, and present to reach data
- ▸The ID (ID token) — the issuer's signed assertion that this person really is who they claim
All seven issues are about checks on those three that were not carried out.
CVE-2026-61466: whatever permissions were requested, were granted
Rated "moderate" — the heaviest of the seven.
OAuth2 allows an application to register itself automatically (dynamic client registration). In doing so, it declares the range of permissions it needs. That range is called a scope.
Apache CXF stored that declaration verbatim. There was no step comparing it against a server-side list of permissions that may be granted.
So whatever a registering application writes on the form goes through. Write yourself administrator-grade scopes and you receive them. It is an entry pass application where the applicant fills in "areas authorized to access" and reception never checks.
Where dynamic registration is open to anyone, the impact grows accordingly. The fix adds validation against a server-defined allowlist.
CVE-2026-68481: revoked passes still worked
Rated "low," but hard to shrug off.
Passes can be revoked. You cut off a departing employee, you suspect a pass has leaked, a user disconnects an integration. The administrator issues a "invalidate this token" operation.
In some Apache CXF implementations, the pass kept working afterwards. Worse, the endpoint that answers "is this pass still valid?" replied that it was, for tokens that had been revoked. Refresh tokens behaved the same way.
The OAuth2 specifications are explicit here: "the authorization server MUST invalidate the token," and introspection of a revoked token MUST return active:false. Neither held.
What makes this dangerous in practice is that it does not look like a failure. The administrator revokes; the screen reports success; they believe the pass is dead. It is not. Nobody finds out until something goes wrong.
CVE-2026-68079: a single-use voucher that worked forever
Rated "low."
The specification says an authorization code MUST NOT be used more than once. Once traded for a pass, the slip is dead. That rule is what makes an intercepted voucher worthless — if the legitimate user redeemed it first, the attacker holds nothing.
In CXF's encrypting data provider, the logic that marks a code as spent was flawed, and the same voucher could be redeemed without limit.
An attacker who captures a voucher even once can therefore keep converting it into passes. The single-use premise simply did not hold.
CVE-2026-57818: submitted simultaneously, the "already used" check never caught up
Rated "low." Similar outcome to the previous one, different cause.
This one occurs in a different storage backend (JCacheCodeDataProvider) and is a timing problem. Between "check whether this voucher is unused" and "mark it used" there was a small gap.
Fire several requests carrying the same voucher at the same instant and they all slip through the moment when the answer is still "unused." One voucher yields multiple valid passes.
Flaws that exploit the gap between checking and acting are called race conditions. Tried sequentially the check works correctly, which is why ordinary testing rarely surfaces them.
CVE-2026-63687: the anti-theft passphrase was quietly overwritten
Rated "low."
To stop vouchers being stolen mid-flight there is a mechanism called PKCE. You commit to a passphrase when the login begins, and must produce the matching one when trading the voucher for a pass. A third party without the passphrase cannot redeem a stolen voucher. Mobile app logins rely on it as standard.
Apache CXF lets a login request be bundled and signed as a single object. In handling that, the signed contents overwrote the values supplied in the outer request unconditionally — including the PKCE passphrase, the anti-replay nonce, and the state value.
Anyone in a position to produce a valid signature — for instance where an application's secret has leaked — could therefore neutralize the anti-theft mechanism entirely. The lock added for safety could be removed from the inside.
CVE-2026-57817: whether the voucher was genuine went unverified
Rated "low." It concerns OpenID Connect, the mechanism for logging in with another service's account.
In its Hybrid Flow, the specification states that the party accepting the login MUST verify a value called c_hash to confirm the presented voucher is genuine. Apache CXF did not enforce that check.
If the identity provider on the other end is non-compliant or misconfigured and omits c_hash, an attacker gains room to substitute the voucher and log in as someone else.
The rating stays at "low" because it only bites when the partner side breaks the spec. That does not change the fact that a check the specification called mandatory was not enforced. Authentication flaws where a verification step gets skipped showed up in several WordPress plugins the same week.
CVE-2026-65583: the ID was accepted without reading it
Rated "low."
Whoever receives an ID token has several things to verify: who issued it, who it was addressed to, how long it is valid, and whether the subject identifier is bound to the signing key. Only with those checks does an ID function as an ID.
In CXF's validation path, a special form — a self-issued ID token — could be accepted with those checks skipped, allowing authentication bypass with a crafted token.
That form is, however, not accepted by default. Only deployments that enabled it are affected, which is why the rating is "low."
Seven of them share one origin: a mandatory check that never ran
Line the login-side seven up again and the symptoms scatter, but the missing pieces cluster in one place.
| What the spec requires | What the code did | CVE |
|---|---|---|
| A voucher MUST NOT be used more than once | Worked indefinitely | 68079 |
| Same | Became several passes when fired at once | 57818 |
| A revoked token MUST be invalidated | Kept working | 68481 |
| The c_hash check is mandatory | Not enforced | 57817 |
| Verify an ID's issuer, audience and expiry | Skipped for one form | 65583 |
| The anti-theft passphrase must be preserved | Overwritable from inside | 63687 |
| The server decides the permission scope | Granted as requested | 61466 |
Everything in the left column is written down in a specification. Most of it is written in the strongest form the standards use — MUST, MUST NOT. These are not the parts open to interpretation.
So why were they missing? Partly because everything works fine without them. No real user redeems a voucher twice. No legitimate user keeps presenting a revoked pass. Routine functional testing surfaces none of these seven. They are the kind of defect that stays invisible as long as everyone behaves correctly.
And all seven came from one researcher, Guanping Zhang. The natural reading is that someone sat down with the specification in hand and checked, clause by clause, whether the implementation actually did what it said. Functional testing produced nothing; reading against the spec produced seven. That gap is the story of these seven.
The takeaway worth carrying: if you run your own login service, "it works" does not mean "it conforms." Revocation especially — you can revoke, see a success message, and still be wrong. It is worth testing once, in your own environment, whether a revoked token is genuinely rejected.
Three others share one origin: configurable, but with no default
The other side has a shared shape too. CVE-2026-54225, CVE-2026-57819, and CVE-2026-64958 differ in symptom and in affected module, but they came about the same way.
The shared pattern
- ▸A setting to impose a limit had existed for a long time
- ▸It was documented, and anyone who looked could configure it
- ▸But no default was set, so doing nothing meant running with no limit
- ▸The fixed versions introduce concrete defaults for the first time (50MB / 500 fields / attachment cap)
This design was once reasonable. The right ceiling depends on the workload, so let the developer choose. Imposing one arbitrarily would break legitimate users who move large files.
The premise, though, was that users read the documentation and configure what they need. In practice, most teams stop working the moment the component is wired in and the thing runs. That is doubly true for a library like Apache CXF, which frequently sits inside another product or development standard — its users may not know the configuration surface exists at all.
This week's fix reads as a decision to move that premise: being configurable and being safe are not the same thing. The same tightening of defaults has been happening elsewhere, including Apache ActiveMQ and Apache Tomcat.
The takeaway for users: when a component's documentation says a limit "can be configured," it is worth checking what the default actually is. "Configurable" does not mean "capped out of the box."
The message inbox was already patched a year ago
The JMS entry point behind CVE-2026-66909 is not new territory for Apache CXF.
Exactly one year earlier, on August 8, 2025, CVE-2025-48913 was published: if untrusted parties could configure JMS, they could point it at an external server and pull code in from there. Rated moderate. The fix rejected the dangerous kinds of references.
| Published | CVE | Where it hit | Direction of the fix |
|---|---|---|---|
| Aug 8, 2025 | CVE-2025-48913 | JMS configuration | Reject dangerous reference types |
| Aug 6, 2026 | CVE-2026-66909 | Restoring data arriving over JMS | Turn the feature itself off by default |
A year ago the answer was to block the dangerous inputs. This time it is to leave the capability switched off unless someone asks for it. The project moved from patching individual hazards to closing the feature and handing out the key on request.
That change has a cost. Organizations genuinely using ObjectMessage for integration may find those flows stop working after the upgrade. The behavior can be restored via configuration, but if you do not check whether you rely on ObjectMessage before updating, you risk taking integration down during business hours. This is the one place where the patch needs advance verification.
Which version to move to
The target depends on the branch you are on.
| Current version | Move to | Effort |
|---|---|---|
| 4.2.0–4.2.2 | 4.2.3 | In-branch update |
| 4.1.0–4.1.7 | 4.1.8 | In-branch update |
| 4.0.x (all) | 4.1.8 (no 4.0 fix exists) | Branch migration |
| 3.6.11 and earlier | 3.6.12 | In-branch update |
| 3.5.x and earlier | 3.6.12 or later (already end of life) | Branch migration |
The branch to watch is 4.0.x. The advisories list the affected range as "4.0.0 and above, below 4.1.8," which includes 4.0.x — yet no 4.0 fix release exists. The official distribution directory carries only the 3.6, 4.1, and 4.2 branches; 4.0 is gone from distribution, though its development history runs through 4.0.11.
If you are on 4.0.x, closing these twelve means migrating to the 4.1 branch — and that is not a version-number swap. Per the official migration guide, 4.0 runs on Java 11 or later and targets Jakarta EE 9.1, whereas 4.1 requires Java 17 and targets Jakarta EE 10.
On a system still running Java 11, that means starting with the Java runtime itself. What looked like patching a vulnerability expands into a platform upgrade plus regression testing. For 4.0.x shops, these twelve are not a "run the update and you're done" event.
One caution: where CXF is bundled inside another vendor's product, such as Red Hat JBoss EAP, do not swap the CXF jars yourself. Wait for the vendor's own update. As of August 6, no vendor has announced when these twelve will be picked up.
If you cannot patch immediately, the advisories imply useful stopgaps. If you do not use ObjectMessage, configure the JMS endpoint to reject that format now and CVE-2026-66909 cannot land. For attachment size and form field count, setting the same values the fix ships (50MB / 500) by hand puts you in an equivalent state ahead of the upgrade.
What is confirmed, and what is not
✓ Confirmed
- ✓All twelve were published by the Apache Software Foundation on August 6, 2026 (verified down to registration timestamps in the official CVE records)
- ✓Fixed versions 4.2.3 / 4.1.8 / 3.6.12 all exist and are downloadable from the official distribution
- ✓Project-assigned severities: 2 important, 2 moderate, 8 low
- ✓All seven login-related issues were reported by the same researcher, Guanping Zhang
- ✓CVE-2026-64958 exists because June's CVE-2026-50645 fix was incomplete
? Not confirmed
- ?Exploitation in the wild — none reported as of August 6. Not listed in the US CISA catalog of known exploited vulnerabilities (KEV) either
- ?Public exploit code — none found
- ?CVSS scores — unassigned for all twelve, pending NVD analysis
- ?Whether this is the full set — the twelve arrived in two waves. No further additions were observed as of the evening of August 6, but more cannot be ruled out
- ?Japanese national advisories — nothing from JPCERT/CC, IPA, or JVN as of August 6
- ?Timelines from vendors that bundle CXF, such as Red Hat — unannounced
- ?Number of affected deployments — no public data
Whether to act tonight depends on where the component sits. If the JMS endpoint is confined to the internal network with no external path to it, the next scheduled maintenance window is fine. If messages arrive from partner companies over an integration link, the priority rises.
And if you use Apache CXF to provide login services, the calculus is different. None of the seven login issues rates highly on its own. But the place where all seven land is the single point that other systems lean on, trusting it to judge correctly. The number to look at is not each severity rating — it is that seven gaps turned up at once in that one point.
Apache CXF is the kind of software that never makes headlines and never reaches a board meeting. Yet business data still moves today across integration paths laid twenty years ago, and underneath them work like this continues. These twelve are part of that quiet record.
Sources
- ▸ Apache CXF: Unsafe deserialization of inbound JMS ObjectMessage (CVE-2026-66909) (August 6, 2026)
- ▸ Apache CXF: XXE via WSDL/XSD import parsing (CVE-2026-65432) (August 6, 2026)
- ▸ Apache CXF: Denial of service via message header attachments (CVE-2026-64958) (August 6, 2026)
- ▸ Apache CXF: Denial of Service attack via large attachments (CVE-2026-54225) (August 6, 2026)
- ▸ Apache CXF: No default restriction on the amount of form parameters per message (CVE-2026-57819) (August 6, 2026)
- ▸ Apache CXF: The authorization code hash (c_hash) is not enforced for the hybrid OIDC flow (CVE-2026-57817) (August 6, 2026)
- ▸ Apache CXF: OAuth2 Dynamic Client Registration Scope Self-Escalation (CVE-2026-61466) (August 6, 2026)
- ▸ Apache CXF: Revocation bypass in DefaultEncryptingOAuthDataProvider (CVE-2026-68481) (August 6, 2026)
- ▸ Apache CXF: DefaultEncryptingCodeDataProvider allows unlimited authorization code replay (CVE-2026-68079) (August 6, 2026)
- ▸ Apache CXF: OAuth2 Authorization Code Replay via TOCTOU in JCacheCodeDataProvider (CVE-2026-57818) (August 6, 2026)
- ▸ Apache CXF: JwtRequestCodeFilter silently overrides outer PKCE and nonce parameters (CVE-2026-63687) (August 6, 2026)
- ▸ Apache CXF: Self-issued ID token claims validation skipped (CVE-2026-65583) (August 6, 2026)
- ▸ NVD - CVE-2026-50645 (the June issue this week's incomplete fix relates to) (June 12, 2026)
- ▸ NVD - CVE-2025-48913 (last year's JMS issue) (August 8, 2025)
- ▸ Apache CXF - Download
- ▸ Apache CXF - Security Advisories
- ▸ Apache CXF - 4.0 Migration Guide

Makoto Horikawa
Backend Engineer / AWS / Django