Skip to content

NMS-20397: Harden Camel JMS - #8922

Open
marshallmassengill wants to merge 4 commits into
foundation-2024from
mm/NMS-20397-smoke
Open

marshallmassengill wants to merge 4 commits into
foundation-2024from
mm/NMS-20397-smoke

Conversation

@marshallmassengill

Copy link
Copy Markdown
Contributor

This is for hardening Camel JMS since Spring 6 is in the upgrade path. This should address a few CVEs.

The stock Camel JMS header filter lets inbound Camel* headers through, so a broker producer can set Camel internals like CamelExecCommandExecutable on a consumer's exchange. Qpid JMS, used by the AMQP event receiver, also deserializes any class from an ObjectMessage by default.

InboundCamelHeaderFilterStrategy drops inbound Camel* headers in any case and defers to the wrapped JMS strategy for everything else. It is applied to the Core queuingservice, the activemq component bundle, the Minion activemq component and the AMQP event receiver. OpenNMS only reads JmsQueueName, SystemId, RpcTracingInfo and SinkTracingInfo off the wire, so no traffic changes.

Assisted by Anthropic Claude Fable 5.1/Opus 5.5.

External References

The stock Camel JMS header filter passes inbound Camel* headers through,
so a producer on the broker could set Camel internals such as
CamelExecCommandExecutable on a consumer's exchange. Qpid JMS, used by
the AMQP event receiver, also deserializes any class from an
ObjectMessage by default.

Add InboundCamelHeaderFilterStrategy, which drops inbound headers that
name a Camel internal header in any case and defers to the wrapped JMS
strategy for everything else. Apply it to the Core queuingservice
component, the activemq component bundle, the Minion activemq component
and the AMQP event receiver. OpenNMS only reads JmsQueueName, SystemId,
RpcTracingInfo and SinkTracingInfo off the wire, so no traffic changes.

Also in this path:
* The AMQP event receiver builds its Qpid connection factory explicitly
  with an empty deserialization allow-list. The receiver only reads
  text messages, and a connection URL option can no longer widen it.
* DaemonContextIT asserts that the queuingservice bean carries the
  filter.
The distributed JMS and ActiveMQ component bundles now reference
org.opennms.core.camel.InboundCamelHeaderFilterStrategy from their
blueprints, so bnd adds an Import-Package for org.opennms.core.camel.
Their Karaf features did not pull in opennms-core-camel, and on Sentinel
opennms-distributed-core-jms is a prerequisite feature that resolves
before the sink features bring the bundle in, so the container failed
to start:

  Unable to resolve org.opennms.features.distributed.jms/33.0.3.SNAPSHOT:
  missing requirement osgi.wiring.package=org.opennms.core.camel
Pulling opennms-core-camel into the Sentinel prerequisite stage exposed
a gap: aalto-xml (needed by netty-codec-xml) imports org.codehaus.stax2
[4.2,5), and the only bundle providing it was stax2-api 4.2.1 from the
cxf-specs feature, which is installed later with the health REST
service. The Sentinel container failed to start:

  Unable to resolve com.fasterxml.aalto-xml/1.3.3: missing requirement
  osgi.wiring.package=org.codehaus.stax2 [4.2.0,5.0.0)

Declare the same stax2-api bundle as a dependency of opennms-core-camel
so the feature resolves standalone. Verified by starting the CI-built
Sentinel image with the patched features repository: sentinel-jms
installs and the JMS bundle becomes Active.
Pulling opennms-core-camel into Sentinel's prerequisite feature stage
(opennms-distributed-core-jms) broke startup a second way: that feature
depends on opennms-core, which brings spring-orm, so spring-orm was now
resolved in the prerequisite stage before hibernate exists. Sentinel runs
Karaf with autoRefresh=false, so spring-orm's optional org.hibernate
imports stayed unwired and the distributed DAO context failed with

  NoClassDefFoundError: org/hibernate/MappingException
  (not found by org.apache.servicemix.bundles.spring-orm)

leaving the health check at "No NodeDao available".

Move InboundCamelHeaderFilterStrategy into a new org.opennms.core.camel.headers
bundle whose only imports are org.apache.camel and org.apache.camel.spi,
with a matching opennms-core-camel-headers feature that needs camel-core
only. The JMS, ActiveMQ component and AMQP receiver blueprints and the core
daemon context use it, and the prerequisite stage gains one small bundle
instead of opennms-core-camel. This also drops the stax2-api addition to
opennms-core-camel, which is no longer needed.

Verified with the CI-built images plus the rebuilt bundles and features:
SentinelSshIT, HealthCheckIT and DaemonContextIT pass locally.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant