This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new fd39ed81cdf7 docs: refresh the security model against the current
codebase (#25054)
fd39ed81cdf7 is described below
commit fd39ed81cdf7368c59e87a9549186161282ae9f1
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Jul 24 13:03:00 2026 +0200
docs: refresh the security model against the current codebase (#25054)
Reconcile docs/.../security-model.adoc with the 4.22.0-SNAPSHOT tree:
- Correct the profile default: the framework applies no profile by
default (security policy `warn`); `prod` (fail) and `dev` (relaxed) are
both explicit opt-ins. `prod` remains the reference posture for triage.
The model previously claimed Camel "defaults to prod".
- Tighten the header-filter namespace to `Camel*`/`camel*` and drop the
stale `org.apache.camel.*` claim (removed in CAMEL-23543 as a Camel 1.x
artifact; the default filter matches `Camel*` case-insensitively).
- Reflect CAMEL-23543 (Camel 4.21): DefaultHeaderFilterStrategy blocks the
`Camel*` namespace by default, in both directions, for every consumer
and producer, with no per-component boilerplate.
- Add a "Configuration variants that change the model" section (profiles,
security-policy levels, per-option opt-ins) consolidating the knobs that
move the trust boundary.
- Refresh the in-scope-class examples with the published 2026 CVE wave
(all IDs verified against the published advisory index).
- Add a machine-readable companion (attachments/security-model.yaml) as a
derived triage index; the prose page remains canonical.
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
---
.../modules/ROOT/attachments/security-model.yaml | 219 +++++++++++++++++
.../modules/ROOT/pages/security-model.adoc | 265 +++++++++++++++++----
2 files changed, 433 insertions(+), 51 deletions(-)
diff --git a/docs/user-manual/modules/ROOT/attachments/security-model.yaml
b/docs/user-manual/modules/ROOT/attachments/security-model.yaml
new file mode 100644
index 000000000000..65d437e0f785
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/attachments/security-model.yaml
@@ -0,0 +1,219 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Apache Camel - Security Model (machine-readable companion)
+#
+# Derived index of docs/user-manual/modules/ROOT/pages/security-model.adoc.
+# The prose page is canonical; regenerate this file whenever it changes.
+# This companion encodes only triage-relevant facts already stated in the
+# prose page and introduces no security commitment not stated there.
+
+meta:
+ title: Apache Camel Security Model
+ canonical_page: docs/user-manual/modules/ROOT/pages/security-model.adoc
+ project_version: 4.22.0-SNAPSHOT
+ status: accepted
+ advisory_index: https://camel.apache.org/security/
+ report_to: [email protected]
+ note: "A report against Camel version N is triaged against this model as it
stood at N, not at HEAD. Provenance and rationale live in the prose page."
+
+roles:
+ - role: committers_and_component_authors
+ trust: trusted
+ - role: route_authors
+ trust: fully_trusted
+ note: "Arbitrary Java/expression execution by a route author is by design."
+ - role: deployment_operators
+ trust: fully_trusted
+ note: "Misconfiguration is operator territory unless a framework default
exposed it."
+ - role: external_message_senders
+ trust: untrusted
+ note: "Primary adversary model - body, headers, attachments, transport
metadata."
+
+trust_boundary:
+ trusted: "the route plus everything the operator configured"
+ untrusted: "the data flowing through the route (Exchange body, headers,
attachments)"
+
+adversary_in_scope:
+ controls: [message_body, message_headers, attachments, transport_metadata]
+ goals: [rce, endpoint_or_bean_redirect, unsafe_deserialization, xxe_ssrf,
path_traversal, auth_bypass, secret_disclosure, backend_query_injection]
+adversary_out_of_scope:
+ - route_authors
+ - deployment_operators
+ - management_surface_network_peers # camel-management, dev console,
jolokia, JMX
+ - transitive_third_party_dependency_authors
+
+component_families:
+ - family: core_router_engine # core/camel-*
+ in_scope: true
+ judged_against: core_router_engine_invariants
+ - family: components # components/camel-*
+ in_scope: true
+ - family: management_surfaces # camel-management, dev console,
camel-jolokia, JMX
+ in_scope: false
+ reason: "trust boundary is the management surface itself, not the MBean
method"
+ - family: deprecated_components
+ in_scope: limited
+ reason: "primary remediation is the documented migration"
+ - family: removed_components
+ in_scope: false
+ - family: examples_and_samples
+ in_scope: false
+
+config_variants:
+ profiles:
+ default: unset
+ values:
+ unset:
+ security_policy_default: warn
+ dev_features: false
+ note: "baseline posture; insecure options remain explicit opt-ins"
+ prod:
+ security_policy_default: fail
+ note: "reference posture against which findings are judged; must be
set explicitly"
+ dev:
+ security_policy_insecure_dev: allow
+ dev_features: true # dev console, debug/trace endpoints,
backlog debugger
+ disposition_if_only_here: "OUT-OF-MODEL: non-default-build"
+ test:
+ security_policy_default: warn
+ dev_features: false
+ disposition_if_only_here: "OUT-OF-MODEL: non-default-build"
+ security_policy:
+ property: camel.security.policy
+ categories: [secret, "insecure:ssl", "insecure:serialization",
"insecure:dev"]
+ levels: [allow, warn, fail]
+ unprofiled_default: warn
+ nature: configuration_linter_at_startup # not a runtime sandbox
+ per_option_opt_ins:
+ - option: allowJavaSerializedObject
+ insecure_value: true
+ default: false
+ - option: transferException
+ insecure_value: true
+ default: false
+ - option: mapJmsMessage
+ insecure_value: true
+ default: true # heritage default, guarded
(CVE-2026-40860, CVE-2026-43866)
+ - option: trustAllCertificates
+ insecure_value: true
+ default: false
+ - option: hostnameVerificationEnabled
+ insecure_value: false
+ default: component-dependent
+
+properties_provided:
+ # id, violation symptom, indicative severity tier
+ - id: no_untrusted_code_execution
+ symptom: "deserialization gadget / bean-method-command dispatch /
expression eval not requested by route"
+ severity: critical
+ - id: no_untrusted_endpoint_redirect
+ symptom: "wire-injected internal header changes dispatch target
(CamelBeanMethodName, CamelHttpUri, ...)"
+ severity: critical
+ - id: no_arbitrary_deserialization
+ symptom: "attacker-chosen types instantiated via
ObjectInputStream/XStream/Hessian/polymorphic-Jackson without filter"
+ severity: critical_when_gadget_reachable
+ - id: no_external_resource_resolution_on_parse
+ symptom: "XML/XSLT/XSD/XPath parse of attacker input reads file / SSRF /
fetches remote DTD/stylesheet"
+ severity: high
+ - id: no_path_escape
+ symptom: "file/mail/ftp path escapes configured root via ../ or absolute
header"
+ severity: high
+ - id: auth_components_enforce
+ symptom: "request served without valid token / unvalidated
issuer-audience-signature / uncovered subpath"
+ severity: critical
+ - id: no_secret_or_state_disclosure
+ symptom: "secrets/bodies/config reach a log (INFO/WARN/ERROR), event,
world-readable file, or HTTP response"
+ severity: medium_to_high
+ - id: no_backend_query_injection
+ symptom: "attacker alters the structure of a Cypher/XSLT-extension/etc
query Camel builds"
+ severity: high_to_critical
+
+core_router_engine_invariants:
+ - no_engine_expression_eval_without_route_author_expression
+ - no_engine_promoted_dispatch_from_untrusted_content
+ - no_type_converter_auto_deserialization_of_arbitrary_types
+ - placeholder_and_bean_ref_resolution_only_on_route_and_config_text
+ - engine_never_promotes_wire_input_into_camel_header_namespace # consumer
HFS responsibility (CVE-2025-27636 family)
+ - error_handling_and_inband_trace_no_eval_or_cross_exchange_disclosure
+ - no_unbounded_resource_guarantee # out of scope
+
+properties_not_provided:
+ - jvm_or_route_sandboxing
+ - availability_under_attacker_volume # DoS / resource exhaustion
+ - application_level_header_sanitisation # only Camel* namespace is
filtered
+ - transitive_dependency_cve_shielding
+ - production_guarantees_under_dev_or_test_profile
+ - information_hiding_at_debug_or_trace_log_levels
+ - protection_from_operator_misconfiguration_outside_defaults
+ - constant_time_or_side_channel_resistant_comparison
+
+false_friends:
+ - "DefaultHeaderFilterStrategy filters the internal Camel* namespace only,
not application headers"
+ - "removeHeaders(Camel*) strips internal-dispatch headers, not every
untrusted header"
+ - "security policy framework is a startup linter, not a runtime sandbox"
+ - "component deprecation is not a security boundary"
+ - "TLS-by-default is not peer authentication"
+
+in_scope_classes:
+ - id: unsafe_deserialization
+ examples: [CVE-2026-40860, CVE-2026-43866, CVE-2026-40859, CVE-2026-43865,
CVE-2026-46590, CVE-2026-40473]
+ - id: xxe_and_remote_resource_resolution
+ examples: [CVE-2014-0002, CVE-2018-8027, CVE-2019-0188]
+ - id: expression_or_template_injection
+ examples: [CVE-2013-4330, CVE-2020-11994]
+ - id: path_traversal
+ examples: [CVE-2018-8041, CVE-2019-0194]
+ - id: ssrf_or_remote_fetch_on_parse
+ examples: [CVE-2017-5643]
+ - id: camel_header_bean_dispatch_abuse
+ examples: [CVE-2025-27636, CVE-2026-40453, CVE-2026-46456, CVE-2026-46457,
CVE-2026-46726, CVE-2026-48205, CVE-2026-48206, CVE-2026-49098, CVE-2026-49099]
+ mitigation_default: "DefaultHeaderFilterStrategy blocks Camel* by default
since 4.21 (CAMEL-23543)"
+ - id: auth_or_authz_bypass
+ examples: [CVE-2026-23552, CVE-2026-40022, CVE-2026-46455, CVE-2026-53913]
+ - id: information_disclosure
+ examples: [CVE-2023-34442, CVE-2024-22371, CVE-2026-49365, CVE-2026-56139]
+ - id: insecure_defaults
+ examples: [CVE-2020-11972, CVE-2020-11973, CVE-2026-40860, CVE-2026-43865]
+ - id: backend_query_injection
+ examples: [CVE-2025-66169, CVE-2026-46591, CVE-2014-0003]
+
+known_non_findings:
+ - "transitive dependency CVE not reachable through Camel code"
+ - "route-author simple/xpath/groovy/jexl/mvel evaluation"
+ - "route-author .bean/.process/Runtime.exec/Class reference"
+ - "Camel* header controls dispatch (intentional contract)"
+ - "application-level header (To/Subject/HTTP X-/JMS/AMQP/MQTT/CoAP/Kafka)
not stripped"
+ - "DefaultHeaderFilterStrategy case bypass (it is case-insensitive by
default)"
+ - "management surface (dev console, backlog debugger, tracer, JMX, jolokia)
exposes code/state"
+ - "finding only under camel.main.profile=dev or test"
+ - "camel-FOO logs Exchange/header/config at DEBUG or TRACE"
+ - "non-cryptographic hash (MD5/SHA-1) used for idempotency/routing/cache
keys"
+ - "deprecated component still ships and has a CVE"
+ - "documented opt-in option enables unsafe behaviour"
+ - "finding in core/camel-* where every core invariant held"
+
+dispositions:
+ - VALID
+ - VALID-HARDENING
+ - "OUT-OF-MODEL: trusted-input"
+ - "OUT-OF-MODEL: adversary-not-in-scope"
+ - "OUT-OF-MODEL: unsupported-component"
+ - "OUT-OF-MODEL: non-default-build"
+ - "BY-DESIGN: property-disclaimed"
+ - KNOWN-NON-FINDING
+ - MODEL-GAP
diff --git a/docs/user-manual/modules/ROOT/pages/security-model.adoc
b/docs/user-manual/modules/ROOT/pages/security-model.adoc
index 267ce346ca4c..67be43f6a879 100644
--- a/docs/user-manual/modules/ROOT/pages/security-model.adoc
+++ b/docs/user-manual/modules/ROOT/pages/security-model.adoc
@@ -251,7 +251,7 @@ against core code, and the triager needs the core-side
statement to judge it.
| Message body or header content reaches placeholder or `#class:` / `#bean:`
resolution and is resolved or instantiated
| Critical (CVSS 9.0-9.8)
-| The engine and the `Exchange` / `Message` model never promote a body field,
attachment or transport metadata into the internal `Camel*` /
`org.apache.camel.*` header namespace; populating that namespace from untrusted
wire input is a _consumer_ responsibility governed by the inbound
`HeaderFilterStrategy` (the CVE-2025-27636 family), not an engine action
+| The engine and the `Exchange` / `Message` model never promote a body field,
attachment or transport metadata into the internal `Camel*` header namespace;
populating that namespace from untrusted wire input is a _consumer_
responsibility governed by the inbound `HeaderFilterStrategy` (the
CVE-2025-27636 family), not an engine action
| Core machinery, rather than a specific consumer, copies an untrusted-origin
value into the internal header namespace
| Critical (CVSS 9.0-9.8)
@@ -301,7 +301,8 @@ routed to "X was not built to do Y" rather than re-argued
case by case.
invariants_.
* *No automatic sanitisation of application-level semantic headers.* The
framework's automatic header filtering is scoped to the internal
- `Camel*` / `org.apache.camel.*` namespace only. Application-level
+ `Camel*` namespace only (matched case-insensitively, so `Camel`, `CAMEL`
+ and `caMEL` are all covered). Application-level
headers that components consume as part of their documented header
contract - `To`, `Cc`, `Bcc`, `Subject`, `From` in `camel-mail`;
arbitrary HTTP header names; JMS properties; AMQP, MQTT, CoAP and Kafka
@@ -315,13 +316,15 @@ routed to "X was not built to do Y" rather than re-argued
case by case.
to pick up an upstream fix, but the CVE itself is closed against the
upstream project. See the third-party-dependency entry in _Out of
scope_.
-* *No production guarantees under the non-default `dev` or `test`
- profile.* The dev console, debug and trace endpoints, the backlog
- debugger and verbose diagnostics are enabled, and the security policy
- default relaxes from `fail` to `warn`. Camel may reveal configuration,
- route and `Exchange` detail that it would not reveal under the default
- `prod` profile. See the profile entry in _Out of scope_ and
- `design/security.adoc`.
+* *No production guarantees under the `dev` or `test` profile.* Under the
+ opt-in `dev` profile the dev console, debug and trace endpoints, the
+ backlog debugger and verbose diagnostics are enabled, and the
+ `insecure:dev` policy is relaxed to `allow`. Camel may reveal
+ configuration, route and `Exchange` detail that it would not reveal in a
+ `prod` deployment. The framework applies no profile by default (security
+ policy `warn`); `prod` must be selected explicitly to escalate the policy
+ to `fail`. See the profile entry in _Out of scope_, _Configuration
+ variants that change the model_ and `design/security.adoc`.
* *No production-grade information-hiding guarantees under non-default
diagnostic log levels.* DEBUG and TRACE log levels are diagnostic, not
production, configurations; they are expected to log internal
@@ -353,8 +356,8 @@ for one. Each is documented here so that a report whose
claim rests on
the misunderstanding can be closed against the correct contract.
* *`DefaultHeaderFilterStrategy` is an internal-namespace filter, not an
- application-header sanitiser.* It filters the `Camel*` /
- `org.apache.camel.*` namespace case-insensitively, which is what
+ application-header sanitiser.* It filters the `Camel*` namespace
+ case-insensitively (`Camel`, `CAMEL` and `caMEL` alike), which is what
contains the internal-dispatch family (the CVE-2025-27636 class). It
does not, and cannot, strip the application-level headers a component
reads as semantic input. Route authors who need application-header
@@ -419,6 +422,17 @@ Historical examples:
* CVE-2026-40860 (`camel-jms`, `camel-sjms`, `camel-sjms2`, `camel-amqp`) -
`JmsBinding.extractBodyFromJms()` calling `ObjectMessage.getObject()` with no
filter while `mapJmsMessage=true` (the default).
+* CVE-2026-43866 (`camel-jms`, `camel-sjms`, `camel-sjms2`) - a forged
+ `DefaultExchangeHolder` carried in a JMS `ObjectMessage` bypassing the
+ `ObjectInputFilter` added for CVE-2026-40860 (a filter-bypass follow-on).
+* CVE-2026-40859 (`camel-vertx-http`, `camel-netty-http`) - raw
+ `ObjectInputStream` deserialisation of HTTP response bodies.
+* CVE-2026-43865 (`camel-hazelcast`) - unsafe Java deserialisation in
+ default-configured managed Hazelcast instances (also an insecure-default
+ case).
+* CVE-2026-46590, CVE-2026-43867 (`camel-pqc`) - HashiCorp Vault and AWS
+ Secrets Manager key-lifecycle managers deserialising persisted key metadata
+ with `ObjectInputStream` (a follow-on to CVE-2026-40048).
==== XML external entity (XXE) and remote DTD/stylesheet resolution
@@ -476,7 +490,17 @@ Historical examples: CVE-2025-27636, CVE-2025-29891
(default HTTP
`HeaderFilterStrategy` bypass), CVE-2025-30177 (`camel-undertow` inbound
filter), CVE-2026-33453 (`camel-coap`), CVE-2026-33454 (`camel-mail`),
CVE-2026-40453 (`camel-jms`, `camel-sjms`, `camel-coap`, `camel-google-pubsub`
-case-variant follow-on).
+case-variant follow-on). The class recurred throughout 2026 in two shapes -
+consumers mapping inbound message headers without an effective
+`HeaderFilterStrategy` (CVE-2026-46456 `camel-aws2-sqs`, CVE-2026-46457
+`camel-nats`, CVE-2026-46726 `camel-vertx-websocket`) and components whose
+non-`Camel`-prefixed header constants bypass the HTTP header filter
+(CVE-2026-46585 `camel-lucene`, CVE-2026-48203 `camel-solr`, CVE-2026-48205
+`camel-dns`, CVE-2026-48206 `camel-jira`, CVE-2026-49098 `camel-kafka`,
+CVE-2026-49099 `camel-salesforce`, among others). This recurrence is what
+motivated centralising the default `Camel*` filter in
+`DefaultHeaderFilterStrategy` (CAMEL-23543, Camel 4.21) so consumers and
+producers block the internal namespace without per-component boilerplate.
The prefixed headers of the API-based components - `CamelFhir.*`,
`CamelBox.*`, `CamelOlingo4.*`, `CamelAs2.*` and the other
@@ -505,7 +529,11 @@ Historical examples: CVE-2026-23552 (`camel-keycloak` not
validating the JWT
`iss` claim against the configured realm), CVE-2026-40022
(`camel-platform-http-main` Vert.x sub-router mounted at `<path>*` while the
auth handler was at the exact path, exposing subpaths of `/api`, `/admin`,
-`/observe/info`).
+`/observe/info`), CVE-2026-46455 (`camel-keycloak` missing the token
+`IS_ACTIVE` check, so an expired access token is accepted) and CVE-2026-53913
+(`camel-keycloak` fail-open: the bearer token is verified only inside the role
+and permission checks, so a deployment configuring neither accepts the request
+unauthenticated).
==== Information disclosure of secrets or sensitive Exchange state
@@ -515,7 +543,10 @@ response.
Historical examples: CVE-2023-34442 (`camel-jira` writing attachments to
world-readable temp files), CVE-2024-22371 (`EventFactory` exposing sensitive
-Exchange data via a custom event).
+Exchange data via a custom event), CVE-2026-49365 (`camel-netty-http`) and
+CVE-2026-56139 (`camel-undertow`) - the `muteException` consumer option
+defaulting to `false`, so a processing error returned the full exception and
+stack trace to the caller.
Judged against the default production log levels (INFO, WARN, ERROR);
findings whose impact only manifests when the operator has enabled the
@@ -533,17 +564,21 @@ deserialisation, TLS validation disabled, an admin
endpoint listening on
question is what an attacker can do against a component the operator simply
added to a route without further configuration.
-Historical examples: CVE-2020-11972, CVE-2020-11973 and CVE-2026-40860 are all
-insecure-default cases that also fall into the deserialisation class.
+Historical examples: CVE-2020-11972, CVE-2020-11973, CVE-2026-40860 and
+CVE-2026-43865 are insecure-default cases that also fall into the
+deserialisation class; CVE-2026-49365 and CVE-2026-56139 (`muteException`
+defaulting to `false`) are insecure-default cases in the
+information-disclosure class.
==== Injection into back-end queries built by Camel
Components that build a query in another language from inputs they receive
must not splice untrusted input directly into that query.
-Historical examples: CVE-2025-66169 (`camel-neo4j` Cypher injection),
-CVE-2014-0003 (`camel-xslt` extension-function invocation from untrusted
-stylesheet input).
+Historical examples: CVE-2025-66169 and its incomplete-fix follow-on
+CVE-2026-46591 (`camel-neo4j` Cypher injection via JSON property names
+interpolated into the query), CVE-2014-0003 (`camel-xslt` extension-function
+invocation from untrusted stylesheet input).
=== Out of scope
@@ -568,18 +603,21 @@ be closed as `not a vulnerability`.
`hostnameVerificationEnabled=false`, explicit selection of an
`ObjectInputStream`-using data format - these are documented opt-ins and the
operator has signed up for the consequences.
-* *Behaviour that is only present under the non-default `dev` or `test`
- profile.* Camel defaults to the `prod` profile; the `dev` and `test`
- profiles (set explicitly via `camel.main.profile`, or selected for you by
- tooling such as Camel CLI) are development-only and deliberately less
- guarded - they enable the developer console, debug and trace endpoints, the
- backlog debugger and more verbose diagnostics, and relax the security policy
- default from `fail` to `warn`. Camel may, by design, reveal configuration,
- route and `Exchange` detail in these modes that it would not reveal under
- `prod`. A report whose impact only manifests under `camel.main.profile = dev`
- or `test` is out of scope as a non-default, development-only configuration;
- the production posture against which findings are judged is the default
- `prod` profile (see _Deployment hardening_ and the `design/security.adoc`
+* *Behaviour that is only present under the `dev` or `test` profile.* The
+ framework applies *no* profile by default; `dev`, `test` and `prod` are all
+ opt-in, set explicitly via `camel.main.profile` (or selected for you by
+ tooling such as Camel CLI, which uses `dev` for local development). The
+ `dev` profile is development-only and deliberately less guarded - it enables
+ the developer console, debug and trace endpoints, the backlog debugger and
+ more verbose diagnostics, and relaxes the `insecure:dev` policy to `allow`.
+ Camel may, by design, reveal configuration, route and `Exchange` detail in
+ these modes that it would not reveal in a production deployment. A report
+ whose impact only manifests under `camel.main.profile = dev` or `test` is
+ out of scope as a development-only configuration. Production deployments are
+ expected to run `camel.main.profile = prod`, under which the security policy
+ escalates from its `warn` default to `fail`; that production posture is the
+ reference against which findings are judged (see _Configuration variants
+ that change the model_, _Deployment hardening_ and the `design/security.adoc`
design document for the profile-aware policy defaults).
* *Denial of service via resource exhaustion.* Unthrottled routes, unbounded
aggregators, an HTTP consumer with no rate limit, a JMS consumer that
@@ -657,11 +695,14 @@ they are, the change is announced through the normal
upgrade-guide channel.
`CamelBeanMethodName`, `CamelFileName`, `CamelExecCommandExecutable` and
`CamelJmsDestinationName` are the public contract for letting a route control
component behaviour. Route authors must filter Camel-internal headers from
- untrusted producers (see _Deployment hardening_ below); component authors
- must apply a strict `HeaderFilterStrategy` on the inbound path.
+ untrusted producers (see _Deployment hardening_ below); on the component
+ side the inbound `Camel*` `HeaderFilterStrategy` is applied by default since
+ 4.21 (CAMEL-23543), and component authors must not opt out of it.
* *The framework's automatic header filtering is scoped to the internal
- `Camel*` / `org.apache.camel.*` namespace.* `DefaultHeaderFilterStrategy`
- filters that namespace case-insensitively; it does not, and cannot, filter
+ `Camel*` namespace.* Since 4.21 (CAMEL-23543) `DefaultHeaderFilterStrategy`
+ filters that namespace case-insensitively *by default, in both directions,
+ for every consumer and producer that uses it*, with no per-component
+ configuration; it does not, and cannot, filter
the non-prefixed application-level headers a component reads as semantic
input - `To`, `Cc`, `Bcc`, `Subject`, `From` in `camel-mail`; HTTP header
names; JMS properties; and so on. Those headers are part of each component's
@@ -716,7 +757,7 @@ Disposition is `KNOWN-NON-FINDING` (see _Triage
dispositions_).
reference allows RCE."* These are route-author primitives by design.
Route code is trusted code; see the route-author entry in _Out of
scope_ and the route-author row in _Roles_.
-* *"A `Camel*` / `org.apache.camel.*` header controls dispatch, therefore
+* *"A `Camel*` header controls dispatch, therefore
the consumer is vulnerable."* Bean-based dispatch via internal headers
is the public contract for letting a route control component behaviour;
see the second bullet under _Known limitations_. A finding is in scope
@@ -861,19 +902,133 @@ not provided_), not to close the report ad hoc.
| _Reporting a vulnerability_ (PMC review), upgrade-guide entry
|===
+== Configuration variants that change the model
+
+The posture described above is not a single fixed setting; a small number of
+profile selections, policy levels and per-component options move where the
+trust boundary sits or how strictly the framework reacts to insecure
+configuration. This section consolidates the knobs that change which
+properties hold, so a report can be judged against the configuration it
+actually requires. It restates facts stated elsewhere in this document in one
+place; it introduces no new commitment.
+
+=== Profiles
+
+Camel applies *no profile by default*. A profile is selected explicitly with
+`camel.main.profile` (or by tooling - the Camel CLI selects `dev` for local
+development). The profile sets the default security-policy level and, for
+`dev`, switches on a set of development features.
+
+[cols="1,3,2",options="header"]
+|===
+| `camel.main.profile` | Security-relevant effect | Triage consequence
+
+| _unset_ (default)
+| The security policy framework defaults to `warn`: insecure configuration in
+ the four categories is logged at startup but does not prevent it. No
+ development features (dev console, backlog debugger, trace endpoints) are
+ enabled.
+| Baseline posture. Insecure *options* remain explicit opt-ins regardless of
+ the policy level (see _Per-option opt-ins_).
+
+| `prod`
+| The security policy framework defaults to `fail`: insecure configuration in
+ the four categories prevents startup. This is the reference posture against
+ which findings are judged.
+| A finding reachable only because the operator relied on the un-profiled
+ `warn` default rather than `fail` is still triaged on the merits of the
+ underlying option, which is itself an opt-in.
+
+| `dev`
+| Development-only. Enables the developer console, debug and trace endpoints,
+ the backlog debugger and verbose diagnostics, and relaxes the `insecure:dev`
+ policy to `allow`.
+| A finding that only manifests under `dev` is `OUT-OF-MODEL:
+ non-default-build`.
+
+| `test`
+| Testing profile used by test tooling. Does not relax the security policy and
+ does not enable the developer console.
+| A finding that only manifests under `test` is `OUT-OF-MODEL:
+ non-default-build`.
+|===
+
+=== Security policy levels
+
+Independently of the profile, each of the four categories (`secret`,
+`insecure:ssl`, `insecure:serialization`, `insecure:dev`) can be set to
+`allow`, `warn` (the un-profiled default) or `fail` through
+`camel.security.policy` and the per-category overrides
+(`camel.security.secretPolicy`, `insecureSslPolicy`,
+`insecureSerializationPolicy`, `insecureDevPolicy`). The policy framework is a
+*configuration linter* that detects insecure configuration at startup (see the
+false-friend note under _Security properties not provided_); it does not
+intercept runtime data. Lowering a category to `allow`, or exempting a property
+via `camel.security.allowedProperties`, is an operator decision and does not by
+itself create a framework vulnerability. See `design/security.adoc` for the
+enforcement design.
+
+=== Per-option opt-ins
+
+A small set of per-component options relaxes a security default when set to a
+non-default value. Their risk is documented and selecting them is an operator
+decision; a finding that requires one of them is `OUT-OF-MODEL:
+non-default-build` (or `BY-DESIGN: property-disclaimed`), per the
+explicit-opt-in entry under _Out of scope_.
+
+[cols="2,1,3",options="header"]
+|===
+| Option | Default | Effect at the insecure value
+
+| `allowJavaSerializedObject=true`
+| `false`
+| An HTTP (or similar) consumer accepts and deserialises
+ `application/x-java-serialized-object` request bodies.
+
+| `transferException=true`
+| `false`
+| Serialised exception objects are transferred over the wire, adding a
+ deserialisation surface on the receiving side.
+
+| `mapJmsMessage=true`
+| `true` (heritage)
+| A JMS `ObjectMessage` body is materialised via `getObject()`; on an untrusted
+ broker this is a deserialisation surface. This heritage default is guarded by
+ an `ObjectInputFilter` (CVE-2026-40860) and a holder-forgery check
+ (CVE-2026-43866).
+
+| `trustAllCertificates=true`
+| `false`
+| TLS server-certificate validation is disabled.
+
+| `hostnameVerificationEnabled=false`
+| component-dependent
+| TLS hostname verification is disabled.
+|===
+
+A machine-readable index of these variants, the entry-point trust levels, the
+in/out-of-scope component families, the claimed and disclaimed properties, the
+known non-findings and the triage dispositions is published alongside this page
+as `security-model.yaml` (an attachment); it is a derived index for automated
+triage and this prose page remains canonical.
+
== Deployment hardening
Operators are responsible for the following. None of these are framework
vulnerabilities if skipped; all of them reduce the attack surface materially.
-* *Stay on the default `prod` profile in production.* Camel defaults to the
- `prod` profile, under which the security policy framework defaults to `fail`
- for the four categories (`secret`, `insecure:ssl`, `insecure:serialization`,
- `insecure:dev`). Setting `camel.main.profile = dev` or `test` is an explicit
- opt-in to development-only behaviour (extra services, dev console, debug
- endpoints) and should not be used in production. Override individual
- categories explicitly when a deployment genuinely needs a relaxed policy.
- See the `design/security.adoc` design document for details.
+* *Explicitly select the `prod` profile in production.* The framework applies
+ no profile by default, and with no profile the security policy framework
+ defaults to `warn` for the four categories (`secret`, `insecure:ssl`,
+ `insecure:serialization`, `insecure:dev`) - insecure configuration is logged
+ but does not stop startup. Set `camel.main.profile = prod` so the policy
+ escalates to `fail` and insecure configuration prevents startup. Setting
+ `camel.main.profile = dev` or `test` is an explicit opt-in to
+ development-only behaviour (extra services, dev console, debug endpoints)
+ and should not be used in production. Override individual categories
+ explicitly when a deployment genuinely needs a relaxed policy. See
+ _Configuration variants that change the model_ and the `design/security.adoc`
+ design document for details.
* *Resolve secrets through a vault.* Use one of the supported backends
(xref:security.adoc[AWS Secrets Manager, Azure Key Vault, Google Secret
Manager, HashiCorp Vault, IBM Secrets Manager, CyberArk Conjur]) rather than
@@ -947,13 +1102,17 @@ When writing a new component or reviewing a pull request
that touches an
existing one, the following questions decide whether the change is in line
with the security model.
-* *Does the component consume untrusted input?* If yes, the inbound side must
- apply a `HeaderFilterStrategy` that blocks `Camel*` and any internal headers
- the component itself uses. The default `DefaultHeaderFilterStrategy` is
- case-insensitive out of the box (so `Camel`, `CAMEL` and `caMEL` are all
- filtered identically); custom strategies must either extend
- `DefaultHeaderFilterStrategy` to inherit this behaviour or implement the
- case-insensitive matching themselves.
+* *Does the component consume untrusted input?* Since 4.21 (CAMEL-23543)
+ `DefaultHeaderFilterStrategy` blocks the `Camel*` namespace by default, in
+ both directions, for every consumer and producer that uses it -
+ case-insensitively (so `Camel`, `CAMEL` and `caMEL` are filtered identically)
+ and with no per-component boilerplate. The remaining responsibilities for a
+ component author are: do not *opt out* of that default (as
+ `ClassicJmsHeaderFilterStrategy` deliberately does for legacy JMS
+ pass-through); when supplying a custom strategy, extend
+ `DefaultHeaderFilterStrategy` (or re-implement the case-insensitive `Camel*`
+ match); and add any of the component's *own* internal headers that fall
+ outside the `Camel*` namespace to the filter set explicitly.
* *Does the component deserialise into a Java object?* If it uses
`ObjectInputStream.readObject()`, an XStream-style unmarshaller or a
polymorphic Jackson reader on input the operator did not explicitly control,
@@ -1009,3 +1168,7 @@ reference to this document.
* link:/security/[Apache Camel Security] - the public
advisory index and reporting process.
* `SECURITY.md` (in the source tree) - the GitHub-rendered security pointer.
+* `security-model.yaml` (attachment to this page) - a machine-readable index of
+ this model (entry-point trust, in/out-of-scope families, config variants,
+ claimed and disclaimed properties, known non-findings, triage dispositions)
+ for automated triage tooling. The prose page is canonical.