VORVEX

CVE-2026-66908: the JWT was valid, but not for your API

The signature and expiration were correct. Even so, a token issued for another service could pass Camel authentication because issuer and audience were not validated.

By Equipe Vorvex4 min read

A JWT with a valid signature is not automatically valid for every API that trusts that key. The token must also have been issued by the expected authority and for the correct audience. CVE-2026-66908 shows what happens when that second part silently disappears: Apache Camel accepted tokens intended for another service as long as they had not expired and were signed by a key in the configured keystore.

This scenario matters especially in companies that share an identity provider across several applications. The attacker does not need to forge a signature or discover the JWT secret. They need to legitimately obtain a token accepted by the same trust domain and present it to an API that should reject that issuer or audience.

Technical diagram showing a valid JWT issued for one application being accepted by a different Apache Camel API because issuer and audience validation are missing
The signature proves that a trusted key issued the token. Without issuer and audience validation, it does not prove that the token belongs to that API.

What CVE-2026-66908 confirms

Apache rates the flaw High and classifies it as CWE-287, Improper Authentication. The NVD record displays a CVSS 3.1 score of 7.5 attributed to CISA-ADP, with vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N; NVD has not yet published its own score. The affected component is camel-platform-http-main from version 4.8.0 up to, but not including, 4.22.0. Both the application HTTP server and the management server went through the vulnerable path.

  • Precondition: JWT authentication enabled with a keystore and neither jwtIssuer nor jwtAudience set
  • What was still validated: token signature and expiration
  • What was not validated: the iss and aud claims
  • Required access: network access, with no prior credential for the target API
  • Version with fail-closed behavior: Apache Camel 4.22.0

Where validation disappeared

According to the advisory, JWTAuthenticationConfigurer.buildJwtOptions returned null when jwtIssuer and jwtAudience were not configured. The caller then skipped JWTAuthOptions.setJWTOptions, and Vert.x JWTAuth was built with only the keystore. The server started normally, with no warning that the applied policy was more permissive than expected. Issuer and audience options only reached the main line in version 4.21.0, so earlier versions did not even provide that control in this component.

http
GET /orders HTTP/1.1
Host: api-b.example
Authorization: Bearer <unexpired-token-for-api-a-signed-by-a-trusted-key>
Accept: application/json
Request format for an authorized environment. The token should come from the lab itself and be valid for another audience; there is no need to alter its signature, payload, or algorithm.

The decisive test is not sending an invalid token. It is comparing two legitimate tokens signed by a trusted key: one whose aud matches the API and another issued for a different audience. Under the vulnerable configuration, both could pass authentication. This makes the finding easy to miss in tests that only check expired tokens, modified signatures, and unsafe algorithms.

Split security diagram comparing complete JWT validation with signature expiry issuer and audience checks against incomplete validation that checks only signature and expiry
Complete validation binds the credential to the expected issuer and resource. Checking only signature and expiration makes the token reusable outside its context.

A signature does not replace context

The signature answers whether the token was modified and whether it came from a trusted key. The iss claim identifies who issued it; aud limits which resource it was created for. With a multi-tenant provider or a keystore that trusts several keys, omitting those two comparisons expands the set of accepted credentials. Even with a single corporate issuer, a token for one internal application may gain access to another API without the IdP ever authorizing that use.

  • Map every issuer and key accepted by the keystore, not only the nominal IdP
  • Request tokens for two controlled audiences and compare the response from the same endpoint
  • Repeat the test against the application server and the management server
  • Reach the backend through its direct path to confirm the gateway is not the only layer validating claims
  • Check whether internal authentication logs distinguish expired tokens, invalid signatures, and wrong audiences

How to triage without exploiting production

The first step can be entirely static. We confirm the resolved version in the build and look for authentication properties in application files, manifests, and charts. The command below sends no traffic and manipulates no token. It reveals whether the component is present and whether the configuration mentions the relevant controls. Secrets should not be copied into the report.

bash
./mvnw -q dependency:tree \
  -Dincludes=org.apache.camel:camel-platform-http-main

rg -n 'authenticationEnabled|jwtKeyStore|jwtIssuer|jwtAudience|jwtAllowMissingIssuerAndAudience' \
  src/main/resources deploy charts
Local, read-only triage. Adjust directories to the repository and review sensitive values without printing them in shared evidence.

After triage, a controlled dynamic test should use tokens issued for the lab and also observe the direct path to Camel. If iss and aud validation exists only at the API gateway, any internal route, alternate ingress, or management port that bypasses the gateway reopens the trust failure.

The fix depends on the release line

Apache's primary recommendation is to upgrade to 4.22.0. In that version, the server refuses to start with a JWT keystore when issuer and audience are both absent, unless the operator explicitly enables jwtAllowMissingIssuerAndAudience. This opt-out defaults to false. The change turns an implicit, permissive policy into a visible configuration decision.

  • Prefer upgrading to Apache Camel 4.22.0 or later
  • On the 4.14.x line, use at least 4.14.9 and configure jwtIssuer, jwtAudience, or both
  • On the 4.18.x line, use at least 4.18.4 and configure jwtIssuer, jwtAudience, or both
  • Do not treat an upgrade to 4.14.9 or 4.18.4 as an automatic fix, the permissive default remains on those lines
  • Keep jwtAllowMissingIssuerAndAudience disabled on 4.22.0 or later
  • Restrict the keystore to the smallest possible key set, ideally with a signer dedicated to the service
  • Ensure the backend and management interface cannot bypass validation performed by the gateway

What this changes in a pentest scope

JWT testing does not end with trying alg none or modifying the signature. An API pentest needs to test the boundary between services: a token that is correct for the user but wrong for the resource; a trusted key but an unexpected issuer; access denied at the gateway but accepted by the backend. CVE-2026-66908 is a good example of a flaw that passes a shallow checklist and appears when testing follows the full identity path, from issuance to every point that makes an access decision.

← Back to blog

Want that same depth applied to your environment?

Tell us what you need to validate and the team scopes a penetration test to match.

Talk on WhatsApp

Ready to assess your company's risk?