Skip to content

CAMEL-24084: Apply header filter strategy to structured-mode CloudEvent extension headers#24724

Open
oscerd wants to merge 1 commit into
apache:mainfrom
oscerd:fix/CAMEL-24084-knative-structured-ce-header-filter
Open

CAMEL-24084: Apply header filter strategy to structured-mode CloudEvent extension headers#24724
oscerd wants to merge 1 commit into
apache:mainfrom
oscerd:fix/CAMEL-24084-knative-structured-ce-header-filter

Conversation

@oscerd

@oscerd oscerd commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

The Knative consumer filters inbound HTTP headers through KnativeHttpHeaderFilterStrategy, so Camel-internal headers (Camel*) are not mapped onto the message. When a CloudEvent is received in structured content mode (application/cloudevents+json), CloudEventProcessors.decodeStructuredContent mapped the remaining event fields (extensions) directly onto the message headers without applying any HeaderFilterStrategy — inconsistent with the binary/HTTP-header path.

This routes structured-mode extension fields through a HeaderFilterStrategy before setting them as headers, so Camel* headers (matched case-insensitively) are filtered consistently on both content modes. Ordinary CloudEvent extension attributes are unaffected.

Changes

  • AbstractCloudEventProcessor: add a HeaderFilterStrategy and a shared mapExtensionAsHeader(...) helper.
  • CloudEventProcessors: route the extension mapping (all spec versions) through the helper.
  • KnativeHttpTest: new test asserting a regular extension is propagated and a Camel*-named field is filtered.
  • Upgrade guide (4.22): documents the consistency change.

Notes

  • On main/4.21.x, DefaultHeaderFilterStrategy filters Camel* inbound by default; the 4.18.x/4.14.x backports will set setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH) explicitly.
  • JIRA: CAMEL-24084

Claude Code on behalf of Andrea Cosentino (@oscerd)

🤖 Generated with Claude Code

…nt extension headers

The Knative consumer filters inbound HTTP headers through KnativeHttpHeaderFilterStrategy,
but structured content mode (application/cloudevents+json) mapped the remaining event fields
(extensions) onto the message headers without a HeaderFilterStrategy, inconsistent with the
binary/HTTP-header path. Route structured-mode extension fields through a HeaderFilterStrategy
so Camel* headers (matched case-insensitively) are filtered consistently on both content modes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@oscerd oscerd requested review from Croway and gnodet July 15, 2026 12:30
@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.

@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.

Good security fix — closes the gap where structured-mode CloudEvent extension fields bypassed the HeaderFilterStrategy that the binary/HTTP-header path already applied.

What works well:

  • Correctly uses DefaultHeaderFilterStrategy.applyFilterToExternalHeaders (IN direction) which filters Camel*/camel* case-insensitively via inFilterStartsWith with lowerCase=true.
  • All three CE spec versions (v1_0, v1_0_1, v1_0_2) are updated consistently.
  • DefaultHeaderFilterStrategy is the right choice here — KnativeHttpHeaderFilterStrategy only adds OUT-direction HTTP headers, so for the IN path they behave identically, and using the base class avoids a cross-module dependency (camel-knative-componentcamel-knative-http).
  • The mapExtensionAsHeader helper centralises the lowercasing + filtering logic nicely.

Test quality:

  • Both positive (regular extension myextension passes through) and negative (camelfilenameCamelFileName is filtered) assertions are present.
  • Parameterised with @EnumSource(CloudEvents.class) to cover all spec versions.

Checklist:

  • Tests included and parameterised
  • Upgrade guide entry added (4.22)
  • Security — consistent filtering on both content modes
  • No public API changes (mapExtensionAsHeader is protected on a package-private class)
  • No other paths with the same gap (binary mode filters at the transport layer; batch mode throws UnsupportedOperationException)

Reviewed with Claude Code on behalf of gnodet. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-knative/camel-knative-component
  • components/camel-knative/camel-knative-http
  • docs

🔬 Scalpel shadow comparison — Scalpel: 11 tested, 28 compile-only — current: 10 all tested

Maveniverse Scalpel detected 39 affected modules (current approach: 10).

⚠️ 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 11 modules (3 direct + 8 downstream), skip tests for 28 (generated code, meta-modules)

Modules Scalpel would test (11)
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-knative
  • camel-knative-http
  • camel-launcher-container
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
  • docs
Modules with tests skipped (28)
  • 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
  • dummy-component

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

All tested modules (39 modules)
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • 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 :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • 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 :: Kamelet Main
  • Camel :: Knative Component
  • Camel :: Knative HTTP
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@davsclaus davsclaus 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, well-scoped security fix that closes a header-injection gap in structured-mode CloudEvent processing.

What was wrong: In binary content mode, KnativeHttpHeaderFilterStrategy filters Camel* headers from inbound HTTP headers. But in structured content mode (application/cloudevents+json), extension fields from the JSON payload were mapped directly onto message headers without any HeaderFilterStrategy — allowing an attacker to inject framework-internal headers (e.g. camelfilename → accessible as CamelFileName via Camel's case-insensitive header map).

Why the fix is correct: DefaultHeaderFilterStrategy defaults to filtering headers starting with Camel/camel (case-insensitive, with lowerCase=true). The new mapExtensionAsHeader() helper lowercases keys with Locale.US before passing them through the filter, so all casing variants are caught — consistent with the binary-mode path.

Test coverage: The new test sends both a regular extension (myextension — asserted to pass through) and a malicious one (camelfilename — asserted to be filtered via Exchange.FILE_NAME == null), correctly exercising Camel's case-insensitive header lookup.

Upgrade guide: Present and well-written.

Claude Code review on behalf of davsclaus. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

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.

3 participants