Visit NES for Apache CXF Home Page

NES for Apache CXF 3.4.x Release Notes

2 versions

Comprehensive release notes and changelog for NES for Apache CXF 3.4.x, including security patches, bug fixes, and feature updates across all supported versions.

Sep 30, 2026
Latest: 3.4.12
31 Patched Vulnerabilities
VEX Statements

September 2026

Full Version:
3.4.10-cxf-3.4.12

Security Fixes

This release patches the following:

  • AttachmentUtil.getAttachment no longer follows unmatched xop:include URLs unless remote URL loading is explicitly enabled (CVE-2024-28752).
  • WadlGenerator can no longer retrieve an arbitrary resource from a request path ending in .xsl when a custom stylesheet is configured (CVE-2024-29736).
  • PbesHmacAesWrapKeyDecryptionAlgorithm can no longer derive keys from JWE PBES2 iteration counts above the configured maximum (CVE-2024-32007).
  • CachedOutputStream can no longer leave file-backed temporary streams unclosed until they exhaust disk space (CVE-2025-23184).
  • The JMS transport now rejects a JNDI PROVIDER_URL whose scheme is not on the allow-list (vm, tcp, nio, ssl, http, https, ws, wss by default; override with -Djms.protocols=<comma-separated list>), so endpoint configuration can no longer point JNDI lookups at an LDAP or RMI server (CVE-2025-48913).
  • JMS listener containers now apply the same JNDI PROVIDER_URL allow-list when they create their JNDI context (CVE-2026-44417).
  • LdapCertificateRepo (the XKMS LDAP certificate repository in cxf-services-xkms-x509-repo-ldap) can no longer interpret caller-supplied certificate identifiers as LDAP filter or distinguished-name syntax (CVE-2026-44930). A PKIX registration whose identifier contains / or is not a valid LDAP DN is now rejected with IllegalArgumentException. There is no opt-out: * and the other filter metacharacters in an identifier are now matched literally, so wildcard lookups stop matching, and a certificate registered earlier under a service name that contains ,, +, ", <, >, ; or \, or starts with # or a space, may need to be registered again.
  • Hardened the XML parsers Apache CXF uses to compile service schemas when schema validation is enabled (CVE-2026-49875). EndpointReferenceUtils now creates its SchemaFactory with JAXP secure processing and with external DTD and external schema access disabled, and W3CMultiSchemaFactory rejects DOCTYPE declarations. On Java 8 with the JDK's built-in XML parser, schemas can still import and include the other documents of the service's own schema collection (for a WSDL-first service, the WSDL's schemas and every document they import or include), but a schema document outside that collection is refused before it is requested, and the service then runs without schema validation and logs SAXException for newSchema(), with no switch to change this (on Java 9 and later such a document is fetched and compiled, as in upstream Apache CXF 3.6.12). Also as in upstream Apache CXF 3.6.12: external DTD entities declared in a schema document are still resolved; the external DTD and schema access restrictions are skipped, with a WARNING, when Apache Xerces 2.x is the JAXP schema factory; and on the Woodstox 6.x validation path, Woodstox's own schema parser is not hardened. Also includes the upstream CXF-9227 fix, so SecurityManager deployments do not need extra permissions for schema resolution.
  • CVE-2026-50623: the OAuth2 token introspection endpoint returned token details to unauthenticated callers when it was deployed without its own authentication filter. It now rejects requests that carry no authenticated principal with 401, as its blockUnauthorizedRequests setting (default true) always intended. Deployments that deliberately serve introspection to unauthenticated callers must now set blockUnauthorizedRequests=false. When blockUnsecureRequests is set to true (the default is false), plain-HTTP requests are now also rejected with 401, as configured.
  • CVE-2026-50627: the local JWT access-token validator (JwtAccessTokenValidator, also used by JwsJwksJwtAccessTokenValidator) checked only the token signature, so a token issued for one resource server could be accepted by another. It now requires an issuer and checks expiry, not-before, issued-at and audience. The audience must equal the request URL, or the expected.claim.audience endpoint property when that is set. Compatibility changes: (1) a token whose audience is not exactly the request URL, such as the service base address or a logical API name, is now rejected, even when OAuthRequestFilter.audience or audienceIsEndpointAddress=false is configured; set expected.claim.audience, or set the validator's validateAudience property to false, if you relied on that. (2) Tokens without iss, and tokens with neither exp nor iat, are now rejected, with no switch to turn this off: a CXF authorization server omits iss unless its data provider's issuer property is set, so set it and re-issue outstanding tokens. (3) A token whose iat is ahead of the resource server's clock is now rejected; set the validator's clockOffset (in seconds) if the clocks can differ. (4) Calling the validator directly, outside a CXF request, now fails unless validateAudience is false. As in upstream Apache CXF 3.6.12, a token with no aud claim is still accepted unless expected.claim.audience or OAuthRequestFilter.audience is configured.
  • OAuthRequestFilter no longer accepts an access token bound to a client IP address from any other address, and no longer rejects requests from the bound address (CVE-2026-50628).
  • CVE-2026-50629 and CVE-2026-50630: control characters in an OAuth2 client_id could forge log lines, and control characters in a configured realm reached the WWW-Authenticate header. Both values are now sanitized: control characters other than TAB are replaced with '_'. Well-formed values are unchanged.
  • CVE-2026-50631: with non-recycled refresh tokens (recycleRefreshTokens=false), concurrent refreshes could drop an access token from its refresh token's list, so revoking the refresh token left that access token valid. Refresh is now atomic per provider instance.
  • JMS JNDI lookups and jndiTransactionManagerName now reject URL-form names and the java.naming.factory.object, java.naming.factory.state and java.naming.factory.url.pkgs environment properties; names that start with one of the JDK's built-in remote naming schemes (corbaname:, iiop:, iiopname:, ldap:, ldaps:, rmi:, dns:) are also rejected, which closes a corbaname: bypass on JDK 8 (CVE-2026-50632).
    • There is no opt-out for the name and environment-property checks (the remote-naming-scheme name check is NES-specific, not in Apache CXF) or for a PROVIDER_URL without ://; -Djms.protocols replaces the default list, so list every scheme you use (for ActiveMQ failover:(tcp://…, the entry failover:(tcp).
    • Provider URLs rejected by default include ActiveMQ failover:(tcp://…), Artemis (tcp://…) HA lists, WebLogic t3:// and t3s://, WildFly remote+http://, JBoss jnp://, TIBCO tibjmsnaming:// and IBM MQ file-system JNDI file: URLs. Each -Djms.protocols entry has :// appended and is matched as a case-sensitive prefix; the property is read once, when JndiHelper is loaded, so set it at JVM start; an empty value rejects every non-empty PROVIDER_URL; and a PROVIDER_URL without :// (for example corbaloc:iiop:… or file:/path) cannot be allowed at all; file:///path can be allowed with a file entry. A deployment that needs one of the three blocked java.naming.factory.* properties must set it JVM-wide instead, as a system property or in jndi.properties; these checks inspect only the endpoint's JNDI environment.
  • DispatchMDBMessageListenerImpl and EJBEndpoint in cxf-integration-jca no longer pass a configured JNDI name to InitialContext.lookup when it contains :// or uses the corbaname, iiop, iiopname, ldap, ldaps, rmi or dns URL scheme, so that configuration can no longer point the lookup at a remote JNDI server (CVE-2026-50633).
  • CVE-2026-50634: JwsJsonContainerRequestFilter and JwsJsonClientResponseFilter accepted a JWS JSON document when any one of its signatures verified, but took the Content-Type, and in the request filter the signed HTTP header values it compares against the request, from the first signature entry, which an attacker could add without a valid signature. Both filters now read that metadata from the signature entry that verified. Only applications that register one of these filters are affected; CXF does not register them by default. The Content-Type is still read from the verified entry's combined protected and unprotected headers, so if the signer leaves cty out of the protected header, an unprotected cty can still set it, as in upstream Apache CXF 3.6.12.
  • AttachmentDeserializer in cxf-core now rejects a MIME attachment part that carries more than 500 distinct header names, so a single multipart request can no longer exhaust memory with an unbounded number of part headers (CVE-2026-50645). Such a part fails with IOException: The attachment contains more headers than are permitted. You can raise the limit with the contextual property attachment-headers-max-count, set as a positive number in a String such as "2000" (an Integer value is ignored), or with the JVM-wide system property org.apache.cxf.attachment-max-headers-count. There is no unlimited setting: a system property of 0 or a negative number rejects every multipart message. The JAX-RS embedded-multipart path does not pick up the contextual property; the default and the system property still apply there.
  • cxf-core now applies a default limit of 50 MiB (52,428,800 bytes) to each inbound MIME attachment when attachment-max-size is not configured, so a single multipart/related (MTOM/SwA) or JAX-RS multipart request can no longer exhaust disk with an arbitrarily large attachment (CVE-2026-54225). A larger attachment is now rejected: SOAP endpoints return a fault caused by CacheSizeExceededException, and JAX-RS multipart requests get HTTP 413. The limit also applies to CXF clients that read large MTOM responses. To accept larger attachments, set attachment-max-size (in bytes) on the endpoint or bus, or set the new JVM-wide system property org.apache.cxf.attachment-max-size. To remove the limit, set it to 0 (for example -Dorg.apache.cxf.attachment-max-size=0). -1 set as the system property, or as a numeric (not String) property value, removes only this attachment limit: a global CachedOutputStream maximum still applies, and CXF logs a WARNING for every spooled part. If you limited attachments only through the global CachedOutputStream maximum (org.apache.cxf.io.CachedOutputStream.MaxSize or bus.io.CachedOutputStream.MaxSize), that value no longer applies to attachments, whether it is smaller or larger than 50 MiB: they now get 50 MiB unless attachment-max-size is set. Set attachment-max-size explicitly to keep your limit. This matches Apache CXF 3.6.12.
  • CVE-2026-57817: the OpenID Connect relying party (IdTokenReader) did not require the c_hash claim for Hybrid Flow ID tokens, so an authorization code was not bound to the ID token. IdTokenReader now requires c_hash when the token response carries response_type code id_token or code id_token token. The CXF OpenID Connect provider (IdTokenResponseFilter) now returns the token's response_type, including plain code, in its token responses for openid tokens. When IdTokenResponseFilter is registered on the implicit or hybrid service, it also returns it in the id_token token and code id_token token authorization responses (the redirect fragment); the code token authorization response is unchanged. As in Apache CXF 3.6.12, c_hash stays optional by default when the token response has no response_type, which is the case for identity providers other than a patched CXF one. Relying parties that use only the Hybrid Flow should call IdTokenReader#setRequireCodeHash(true). With that setting, token refresh (which has no authorization code) no longer requires c_hash.
  • CVE-2026-57818: JCacheCodeDataProvider could let one authorization code be redeemed several times by concurrent token requests. Code removal is now a single atomic JCache getAndRemove. If you subclass JCacheCodeDataProvider and override getCodeGrant(String), that override is no longer called when a code is redeemed, so move that logic into an override of removeCodeGrant(String).
  • The JAX-RS form parameter limit (maxFormParameterCount) had no default, so an unauthenticated client could post an application/x-www-form-urlencoded or multipart/form-data body with an unlimited number of parameters and exhaust CPU and memory (CVE-2026-57819). The limit now defaults to 500: a request with 500 or more form parameters is rejected with HTTP 413, so at most 499 are accepted. Set maxFormParameterCount higher to allow more, or to -1 to disable the limit. For multipart/form-data, the attachment count limit from the CVE-2026-64958 fix (attachment-max-count, default 50 parts, HTTP 500) is checked first, so raise it as well. The OAuth 1.0 module (cxf-rt-rs-security-oauth) also gets the 500-parameter limit, but its request-token, access-token and authorization endpoints answer such a form with HTTP 500, not 413, and log it at SEVERE. As in Apache CXF 3.6.12, the form body is still read in full before its parameters are counted, and the size of a form body is not limited by default. Upgrade cxf-core together with cxf-rt-frontend-jaxrs: the new cxf-rt-frontend-jaxrs fails with NoSuchMethodError next to an older cxf-core.
  • CVE-2026-61466: OAuth2 dynamic client registration stored whatever scopes the registering client asked for. Requested scopes are now checked against the new allowedClientScopes setting or, when unset, the data provider's permission map. Compatibility: registration and update requests that name a scope outside allowedClientScopes, or, when that is unset, outside the data provider's permission map, now fail with HTTP 400 invalid_client_metadata. The permission map is empty unless configured, so without allowedClientScopes every request that names a scope, openid included, is rejected. Set allowedClientScopes, or populate the permission map (permissionMap or supportedScopes). There is no switch that turns the check off. Without allowedClientScopes, registrants can still request any scope the permission map defines and a registration provider that does not extend AbstractOAuthDataProvider gets no scope check, so configure allowedClientScopes to restrict dynamically registered clients. A registration that names no scope is not checked and is unrestricted, with or without allowedClientScopes.
  • CVE-2026-63687: JwtRequestCodeFilter let claims in a signed request object override the outer request's code_challenge, code_challenge_method, nonce and state. Those four parameters are now taken only from the outer request; clients that send them only inside the request object must also send them as query parameters. There is no server-side switch, and with OpenID Connect implicit or hybrid flows a request whose nonce is only in the request object is now rejected at the authorization endpoint.
  • cxf-core and cxf-rt-frontend-jaxrs now enforce the attachment count limit (attachment-max-count, default 50 per message) on every path that reads MIME attachments, so a single multipart request with thousands of parts can no longer exhaust memory and CPU (CVE-2026-64958). Before this fix the limit applied only when all attachments were loaded at once. Iterating over the attachments, hasNext, add/addAll, the DataHandler map, XOP cid: lookups and the JAX-RS MessageContext multipart builder read every part without a limit. A message with more attachments than the limit is now rejected on all of these paths, also when a CXF client reads a multipart response. JAX-RS counts every part, the first one included, and answers HTTP 500, so a multipart/form-data request with more than 50 fields now fails. If you need more, raise attachment-max-count on the endpoint or bus; for nested (embedded) JAX-RS multipart only a value set on the message itself takes effect.
  • CVE-2026-65432: when CXF loaded a WSDL, documents reached through wsdl:import or xsd:import were parsed by WSDL4J with external entities enabled, and WSDLManager.getDefinition(Element) let WSDL4J fetch imports itself. A DOCTYPE in an imported WSDL or XSD could read local files or make outbound requests (XXE, CWE-611). CXF now re-parses each imported document through its hardened StaxUtils reader before WSDL4J sees it, on both the URL and the DOM-element load paths, as Apache CXF 3.6.12 does. Behaviour changes (identical to upstream): a DTD-declared entity reference in an imported document is now dropped without error from an attribute value (for example, targetNamespace="&tns;" becomes empty), and makes the load fail with IllegalStateException when it appears in element text; imports are subject to the StaxUtils reader limits that already applied to the top-level WSDL (org.apache.cxf.stax.* system properties); and relative imports in a WSDL loaded with getDefinition(Element) now resolve against that document's URI (before, they were resolved against the parent of the process working directory). There is no switch for the entity handling, or for the URI-scheme check that absolute imports in a WSDL loaded with getDefinition(Element) now get (this line accepts only file, http, https, classpath and jar, fewer than Apache CXF 3.6.12), so replace entity references in imported documents with literal text and use one of those schemes.
  • CVE-2026-65583: with the non-default setSupportSelfIssuedProvider(true), OidcClaimsValidator accepted self-issued ID tokens without validating subject, audience, expiry, issued-at and not-before, and decided whether to verify a token with its own embedded sub_jwk key from a non-standard issuer claim instead of iss, so an attacker-signed token could pass as one from the configured provider. Self-issued tokens now get the same claim checks as other ID tokens, must carry a sub_jwk whose JWK thumbprint matches sub, and are recognised by iss only. Deployments that leave the flag off (the default) are not affected by the vulnerability. In all configurations, including the default, ID tokens that are not self-issued get the same checks as before, but azp is now checked before sub: a token that fails both is still rejected, now with Invalid authorized party instead of Invalid subject. With the flag on and no issuer ID configured, spec-shaped self-issued tokens (iss=https://self-issued.me, no issuer claim) are now accepted after full validation, where they were rejected before.
  • CVE-2026-66909: the JMS transport (cxf-rt-transports-jms) deserialized the body of every inbound JMS ObjectMessage before any interceptor ran, on services and on client replies. Anyone able to write to a CXF JMS destination could therefore trigger native Java deserialization. Inbound ObjectMessage is now rejected by default ("ObjectMessage is disabled by configuration"). Behaviour changes: (1) services reject ObjectMessage requests unless the endpoint sets allowObjectMessages=true (jms: URI parameter or JMSConfiguration.setAllowObjectMessages). This includes messageType=binary requests from CXF clients without this fix and ObjectMessage from non-CXF producers. (2) Clients reject ObjectMessage replies unless allowObjectMessages=true. (3) Binary payloads are now sent as BytesMessage instead of ObjectMessage, both by clients configured with messageType=binary and in service replies (to ObjectMessage requests, or with MTOM and messageType=binary); set useObjectMessageFallback=true on the sending side to restore the old behaviour for consumers that require ObjectMessage. allowObjectMessages=true restores unrestricted deserialization: there is no class allow-list, so enable it only when every producer that can write to the destination is trusted. A service that sets allowObjectMessages=true for legacy clients that expect ObjectMessage replies must also set useObjectMessageFallback=true. One residual remains, shared with every upstream fixed release: on services, some JMS providers (for example ActiveMQ Classic) still deserialize an inbound ObjectMessage while CXF builds its receive log message, before the rejection. This happens whatever the log level is. Keep the provider's own class filtering (ActiveMQ trusted packages) enabled.
  • CVE-2026-68079: DefaultEncryptingCodeDataProvider accepted the same authorization code any number of times. Codes are now single-use, and deleting a client invalidates its outstanding codes. Behaviour change: the provider accepts a code only while it is in the provider's in-memory set of live codes. Listing grants no longer consumes them, and a code issued before a restart, or by another node that shares the encryption key, is rejected. Authorization servers with more than one node must route each /token request to the node that issued the code, because codes live in that node's memory; other nodes answer invalid_grant. A restart invalidates every outstanding code. There is no setting to restore the old behaviour. This matches the upstream Apache CXF fix and is not an NES change. Applications that use this provider also need the fix for CVE-2026-68481.
  • CVE-2026-68481: DefaultEncryptingOAuthDataProvider (and DefaultEncryptingCodeDataProvider) kept accepting access and refresh tokens after they were revoked or rotated away. Revoked tokens are now rejected; tokens are valid only in the provider instance that issued them since it started. There is no configuration switch: with a fixed or shared SecretKey, the upgrade restart invalidates all outstanding access and refresh tokens, and clustered or separate resource-server deployments must send token validation, refresh and revocation to the issuing instance. Token revocation is also serialized with non-recycled refreshes (recycleRefreshTokens=false), as in upstream CXF 3.6.12.

3.4.11

Released Sep 27, 2026
Full Version:
3.4.10-cxf-3.4.11

Notes

  • This release originates from the open‑source Apache CXF repository forked by HeroDevs. It encompasses modifications implemented by HeroDevs to ensure successful framework builds. This release contains no functional changes from Apache CXF 3.4.10.

Stay in the loop

~/herodevs-spring-framework-support

Open Source Support

When official support ends, we're just getting started.