Skip to content

CAMEL-24436/24450/24452/24456: CORS and credential scoping fixes, backport to camel-4.22.x - #25937

Merged
Croway merged 4 commits into
apache:camel-4.22.xfrom
oscerd:backport/glasswing-cors-credentials-4.22.x
Aug 31, 2026
Merged

CAMEL-24436/24450/24452/24456: CORS and credential scoping fixes, backport to camel-4.22.x#25937
Croway merged 4 commits into
apache:camel-4.22.xfrom
oscerd:backport/glasswing-cors-credentials-4.22.x

Conversation

@oscerd

@oscerd oscerd commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Backport to camel-4.22.x of four fixes already reviewed and merged on main. All four are about a credential or a CORS grant reaching a party the operator never named.

Straight cherry-picks, applied in the order they merged on main, with no manual conflict resolution. The upgrade-guide entries are not included: the guides for every line live on main.

Behaviour changes to be aware of when upgrading a patch release:

  • enableCORS=true on jetty no longer installs Jetty's allow-all CrossOriginFilter defaults. A deployment that relied on any origin being accepted must now name its origins.
  • platform-http-vertx sends Access-Control-Allow-Credentials only when the request origin matched a configured origin. With no origin list the origin is still reflected as before, but credentials are not granted, and Vary: Origin is now set.
  • camel-http stops re-attaching Authorization on cross-authority redirects when followRedirects=true.

Built and tested per module on this branch (camel-http, camel-jetty-common, camel-jetty, camel-platform-http-vertx), including the new and touched tests: HttpOAuth2TokenCachingTest, HttpOAuth2RedirectTokenLeakTest, HttpClientConfigurerOverrideTest, EnableCORSTest, VertxPlatformHttpEngineTest.

Claude Code on behalf of oscerd

oscerd and others added 4 commits August 31, 2026 10:08
…hat shapes the token (apache#25834)

* CAMEL-24456: camel-http - key the OAuth2 token cache on every field that shapes the token

The cache key was the record OAuth2URIAndCredentials(uri, clientId, clientSecret), while
scope, tokenEndpoint and resourceIndicator all influence the token that
getAccessTokenResponse() mints. The map is static, so it is shared by every
OAuth2ClientConfigurer instance and every CamelContext in the JVM.

A route configured with a narrow scope could therefore be handed a broad-scope token that
another route had cached first for the same target and credentials, which defeats the
scoping the operator configured and makes the audit trail misleading. Where several
CamelContexts run in one JVM, a token minted for one could serve another's requests.

Add tokenEndpoint, scope and resourceIndicator to the key. The map stays JVM wide, but a
hit now requires every field of the token request to match, so it is the same token
request by construction; scoping the cache per CamelContext is noted on the issue as a
separate question.

The added test follows the idiom of the tests around it: cache a token, close the token
endpoint, then request the same target with a different scope. A cache hit succeeds, a
miss cannot mint and fails - so without the fix the narrow-scope token is silently reused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrea Cosentino <ancosen@gmail.com>

* CAMEL-24456: Regenerate YAML DSL schema

---------

Signed-off-by: Andrea Cosentino <ancosen@gmail.com>

(cherry picked from commit 4e2ddab)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… the operator did not name (apache#25829)

enableCORS=true added new CrossOriginFilter() with no init parameters, so Jetty's own
defaults applied. Confirmed against jetty-ee10-servlets 12.1.12: DEFAULT_ALLOWED_ORIGINS
is "*" and credentials default to true. The filter reflects the request's origin rather
than sending "*", so that pairing is the credentialed any-origin configuration the fetch
specification refuses to express - reflecting the origin being the usual way around that
rule. An option named "enable CORS" should not mean "every origin, with credentials".

Default allowCredentials to false when CORS is enabled. The origin is still reflected, so
enabling CORS keeps working for requests that carry no credentials; an operator who needs
credentialed cross-origin requests sets filterInit.allowCredentials=true and names the
origins in filterInit.allowedOrigins. Asking for credentials while leaving the origins at
"*" is logged as a warning, since that combination reproduces the original behaviour.

The defaults are applied where the init parameter map is built, not where the filter is
added: the map is handed to the endpoint earlier and only when it is non-empty, so
applying them later would drop them in exactly the case that matters - enableCORS on its
own, with no filterInit parameters at all.

EnableCORSTest.testCORSenabled asserted that credentials are granted, so it encoded the
previous behaviour; it now asserts the opposite, and a second test covers the opt-in.

Matches the change made to camel-platform-http-vertx under CAMEL-24436.

Signed-off-by: Andrea Cosentino <ancosen@gmail.com>

(cherry picked from commit 6e3e4ec)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… endpoint was not configured with (apache#25830)

CAMEL-24452: camel-http - do not send credentials to a host the endpoint was not configured with

Two paths handed credentials to a redirect target, which is a host chosen by the remote
server rather than by the route, once followRedirects=true.

OAuth2ClientConfigurer registers its interceptor with addRequestInterceptorFirst, and
HttpClient runs protocol-level request interceptors inside ProtocolExec, which sits below
RedirectExec in the exec chain. The interceptor therefore ran again for every redirect hop
and re-attached Authorization: Bearer <token> to whatever host the Location header named.
It now attaches the token only for the endpoint's own host.

HttpCredentialsHelper.getCredentialsProvider() was called with the endpoint's authHost,
which is optional and null in the common basic-auth configuration, making the scope
new AuthScope(null, -1) - any host, any port, any scheme. HttpClient then offered the
credentials to whichever host issued a 401 challenge. The scope now falls back to the
endpoint's host when authHost is not set; an explicit authHost still takes precedence.

Both need to know the host the endpoint addresses, which createHttpClientConfigurer did
not receive. Rather than change that protected signature, a three argument overload
carries the target URI and the existing two argument form delegates to it with null, so
any subclass overriding or calling it keeps the previous behaviour.

The added test drives a real redirect from a server answering to localhost to a second one
answering to 127.0.0.1 - a single server will not do, because the bootstrap sets a
canonical host name and answers 421 to a mismatched Host. Without the fix the first case
delivers "Bearer xxx.yyy.zzz" and the second "Basic c2NvdHQ6dGlnZXI=" to the redirect
target.

Signed-off-by: Andrea Cosentino <ancosen@gmail.com>
Signed-off-by: Croway <federico.mariani.1990@gmail.com>

(cherry picked from commit 3a6c27b)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…for a configured origin (apache#25820)

createCorsHandler() set Access-Control-Allow-Credentials: true outside the origin
check, so it went out on every response to a request carrying an Origin header -
including responses to origins the handler had just decided not to allow. And when
camel.server.cors.origins is unset, allowsOrigin is true for every origin and the
caller's own Origin is echoed back as Access-Control-Allow-Origin. Together those
produce the credentialed any-origin configuration the fetch specification refuses to
express as "*", which is why reflecting the origin is the usual way around that rule.

Send Access-Control-Allow-Credentials only when the request origin matched an origin
the operator actually configured. With no origin list the origin is still reflected,
as before, but credentials are not granted. Also add Vary: Origin whenever the origin
is reflected, so a shared cache cannot serve one origin's response to another.

Signed-off-by: Andrea Cosentino <ancosen@gmail.com>

(cherry picked from commit 4b557e4)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-http
  • components/camel-jetty-common
  • components/camel-jetty
  • components/camel-platform-http-vertx

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.


🔬 Scalpel shadow comparison — Scalpel: 63 tested, 29 compile-only — current: 63 all tested

Maveniverse Scalpel detected 92 affected modules (current approach: 63).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 63 modules (4 direct + 59 downstream), skip tests for 29 (generated code, meta-modules)

Modules Scalpel would test (63)
  • camel-a2a
  • camel-as2
  • camel-clickup
  • camel-consul
  • camel-cxf-rest
  • camel-cxf-soap
  • camel-cxf-spring-rest
  • camel-cxf-spring-soap
  • camel-cxf-spring-transport
  • camel-cxf-transport
  • camel-graphql
  • camel-http
  • camel-java-joor-dsl
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-jetty
  • camel-jetty-common
  • camel-jsonpath
  • camel-kamelet
  • camel-knative-http
  • camel-kubernetes
  • camel-launcher-container
  • camel-lra
  • camel-mcp-server
  • camel-micrometer-observability
  • camel-micrometer-prometheus
  • camel-netty-http
  • camel-oauth
  • camel-observability-services
  • camel-openapi-validator
  • camel-opentelemetry
  • camel-opentelemetry2
  • camel-platform-http
  • camel-platform-http-jolokia
  • camel-platform-http-main
  • camel-platform-http-vertx
  • camel-quickfix
  • camel-rest-openapi
  • camel-restdsl-openapi-plugin
  • camel-sap-netweaver
  • camel-slack
  • camel-soap
  • camel-spring-rabbitmq
  • camel-telegram
  • camel-telemetry
  • camel-telemetry-dev
  • camel-test-main-junit5
  • camel-test-main-junit6
  • camel-undertow
  • camel-undertow-spring-security
  • camel-vertx-http
  • camel-webhook
  • camel-whatsapp
  • camel-xml-io-dsl
  • camel-xml-jaxb-dsl
  • camel-xml-jaxb-dsl-test-definition
  • camel-xml-jaxb-dsl-test-spring
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
  • camel-zookeeper
Modules with tests skipped (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • components/camel-jetty: 1 test(s) disabled on GitHub Actions
Build reactor — dependencies compiled but only changed modules were tested (92 modules)
  • Camel :: AI :: A2A
  • Camel :: AI :: MCP Server
  • Camel :: AS2 :: Component
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: CXF :: REST
  • Camel :: CXF :: REST :: Spring
  • Camel :: CXF :: SOAP
  • Camel :: CXF :: SOAP :: Spring
  • Camel :: CXF :: Transport
  • Camel :: CXF :: Transport :: Spring
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: ClickUp
  • Camel :: Common Telemetry
  • Camel :: Component DSL
  • Camel :: Consul
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: GraphQL
  • Camel :: HTTP
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: JSon Path
  • Camel :: Java DSL with jOOR
  • Camel :: Jetty
  • Camel :: Jetty :: Common
  • Camel :: Kamelet
  • Camel :: Kamelet Main
  • Camel :: Knative HTTP
  • Camel :: Kubernetes
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: Long-Running-Action
  • Camel :: Maven Plugins :: OpenApi REST DSL Generator
  • Camel :: Micrometer :: Observability 2
  • Camel :: Micrometer :: Prometheus
  • Camel :: Netty HTTP
  • Camel :: OAuth
  • Camel :: Observability Services
  • Camel :: OpenAPI :: Validator
  • Camel :: OpenTelemetry (deprecated)
  • Camel :: Opentelemetry 2
  • Camel :: Platform HTTP
  • Camel :: Platform HTTP :: Jolokia
  • Camel :: Platform HTTP :: Main
  • Camel :: Platform HTTP :: Vert.x
  • Camel :: QuickFIX/J
  • Camel :: REST OpenApi
  • Camel :: SAP NetWeaver
  • Camel :: SOAP
  • Camel :: Slack
  • Camel :: Spring RabbitMQ
  • Camel :: Telegram
  • Camel :: Telemetry :: Dev
  • Camel :: Test :: Main :: JUnit5
  • Camel :: Test :: Main :: JUnit6
  • Camel :: Undertow
  • Camel :: Undertow Spring Security
  • Camel :: Vert.x :: HTTP
  • Camel :: Webhook
  • Camel :: Whatsapp
  • Camel :: XML DSL Jaxb :: Test :: Definition
  • Camel :: XML DSL Jaxb :: Test :: Spring
  • Camel :: XML DSL with camel-xml-io
  • Camel :: XML DSL with camel-xml-jaxb
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin
  • Camel :: Zookeeper

⚙️ View full build and test results

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean cherry-pick backport of four already-reviewed security fixes (CORS and credential scoping) to camel-4.22.x.

All four original PRs were previously reviewed:

Straight cherry-picks with no manual conflict resolution, matching the sibling backport to camel-4.18.x (#25938).

📋 PR Metadata

Aspect Current Suggested
Labels components + bug
Milestone (none) 4.22.0

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@Croway
Croway merged commit b0399b1 into apache:camel-4.22.x Aug 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants