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 d5a717dd0f8a CAMEL-23588: camel-undertow - extend
UndertowHeaderFilterStrategy to filter the legacy websocket.* exchange-header
prefix (#23522)
d5a717dd0f8a is described below
commit d5a717dd0f8a60cc6f89933450dce0c6c1944ac8
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Jun 8 09:53:47 2026 +0200
CAMEL-23588: camel-undertow - extend UndertowHeaderFilterStrategy to filter
the legacy websocket.* exchange-header prefix (#23522)
---
.../undertow/UndertowHeaderFilterStrategy.java | 19 +++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc | 47 ++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHeaderFilterStrategy.java
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHeaderFilterStrategy.java
index 67fb6f2054dd..9c112b06294c 100644
---
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHeaderFilterStrategy.java
+++
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowHeaderFilterStrategy.java
@@ -22,10 +22,29 @@ import org.apache.camel.http.base.HttpHeaderFilterStrategy;
public class UndertowHeaderFilterStrategy extends HttpHeaderFilterStrategy {
+ /**
+ * Legacy {@code websocket.*} Exchange-header prefix used by {@code
UndertowConstants} for the dispatch and event
+ * headers ({@code websocket.connectionKey}, {@code
websocket.connectionKey.list}, {@code websocket.sendToAll},
+ * {@code websocket.eventType}, {@code websocket.eventTypeEnum}, {@code
websocket.channel},
+ * {@code websocket.exchange}). Added to the in/out filter prefixes
(CAMEL-23588) so the undertow boundary does not
+ * propagate these values onto outbound wire frames or map them in from
inbound HTTP-style headers. This is
+ * defence-in-depth — cross-component routes that flow an untrusted
message into an undertow producer should also
+ * {@code .removeHeaders("websocket.*")} at the trust boundary, because
the producer reads these headers via
+ * {@code in.getHeader(...)} which bypasses the {@code
HeaderFilterStrategy}.
+ */
+ static final String WEBSOCKET_FILTER_STARTS_WITH = "websocket.";
+
public UndertowHeaderFilterStrategy() {
initialize();
}
+ @Override
+ protected void initialize() {
+ super.initialize();
+ setOutFilterStartsWith("Camel", "camel", WEBSOCKET_FILTER_STARTS_WITH);
+ setInFilterStartsWith("Camel", "camel", WEBSOCKET_FILTER_STARTS_WITH);
+ }
+
@Override
public boolean applyFilterToExternalHeaders(String headerName, Object
headerValue, Exchange exchange) {
boolean skip = HttpString.tryFromString(headerName) == null;
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
index 5dc446b2d84c..346a9aa8e2ad 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
@@ -1000,6 +1000,53 @@ jmsComponent.setHeaderFilterStrategy(new
ShiroFriendlyJmsHeaderFilterStrategy())
A worked example is in `ShiroOverJmsTest` in the `camel-itest` module.
+
+=== camel-undertow - potential breaking change
+
+`UndertowHeaderFilterStrategy` now also filters the legacy `websocket.*`
+Exchange-header prefix (in addition to the `Camel*` / `camel*` /
+`org.apache.camel.*` prefixes it already filtered). This applies to both the
+in (wire -> exchange) and out (exchange -> wire) directions and follows the
+dedicated-filter-strategy shape used by CAMEL-23532 for
+`camel-vertx-websocket` / `camel-atmosphere-websocket` / `camel-iggy`.
+
+The constants in `UndertowConstants` (`CONNECTION_KEY`, `CONNECTION_KEY_LIST`,
+`SEND_TO_ALL`, `EVENT_TYPE`, `EVENT_TYPE_ENUM`, `CHANNEL`, `EXCHANGE`) keep
+their existing string values (`websocket.connectionKey`,
+`websocket.connectionKey.list`, `websocket.sendToAll`, etc.) because they are
+part of the undertow component's externally-visible API contract; routes
+referencing them (symbolically or by literal value) continue to work
+unchanged within an undertow route.
+
+The behaviour change applies at undertow's transport boundary:
+
+* Outbound (exchange -> wire): if an exchange ends up at an undertow producer
+ carrying an Exchange header whose name starts with `websocket.`, that
+ header will no longer be propagated onto the outbound HTTP/websocket
+ request as a wire-level header.
+* Inbound (wire -> exchange): if an undertow consumer receives a request
+ whose wire-level headers include a name starting with `websocket.`, that
+ header will no longer be mapped into the resulting Camel exchange.
+
+Note that the `HeaderFilterStrategy` only governs the transport boundary; it
+does not prevent cross-component header injection (for example, an
+`http -> undertow` route where the HTTP consumer maps an attacker-supplied
+`websocket.connectionKey` header into the exchange and the undertow producer
+then reads it via `in.getHeader(...)` to dispatch to a specific peer). For
+defence in depth at the trust boundary, route authors should explicitly strip
+these headers from untrusted inbound traffic, for example:
+
+[source,java]
+----
+from("jetty:http://0.0.0.0:8080/api")
+ .removeHeaders("websocket.*")
+ .to("undertow:ws://internal-broker/notifications");
+----
+
+Routes that intentionally relied on undertow mapping `websocket.*` wire
+headers in or out can supply a custom `headerFilterStrategy` endpoint option
+to restore the previous behaviour.
+
=== camel-web3j - potential breaking change
The Exchange header constants in `Web3jConstants` have been renamed to follow
the