31 lines
3.1 KiB
Markdown
31 lines
3.1 KiB
Markdown
# Apache ActiveMQ CWE-407 Scan — CLEAN (deeper scan, beyond activemq-0001)
|
||
|
||
**Date:** 2026-03-27
|
||
**Repo:** https://github.com/apache/activemq
|
||
**Scan scope:** `activemq-broker/src/main/java/org/apache/activemq/broker/region/RegionBroker.java`, `network/NetworkConnector.java`, `network/NetworkBridgeConfiguration.java`, `network/DemandForwardingBridgeSupport.java`, `broker/region/Queue.java`, `broker/region/cursors/OrderedPendingList.java`, `broker/BrokerService.java`, `broker/TransportConnector.java`
|
||
|
||
## Findings
|
||
|
||
No new CWE-407 defects found beyond the existing `activemq-0001` patch.
|
||
|
||
### Candidates examined
|
||
|
||
| File | Location | Pattern | Verdict |
|
||
|------|----------|---------|---------|
|
||
| `broker/region/RegionBroker.java` | destination lookup | `destinations.containsKey(destination)` — uses `ConcurrentHashMap`; O(1) | CLEAN |
|
||
| `network/NetworkBridgeConfiguration.java` | `excludedDestinations`, `dynamicallyIncludedDestinations`, `staticallyIncludedDestinations` | `CopyOnWriteArrayList` — iterated in `isPermissableDestination()` per consumer subscription, not per message; lists are configuration-time, typically 0–5 entries | CLEAN (config-bounded) |
|
||
| `network/DemandForwardingBridgeSupport.java` | `duplicateSuppressionIsRequired()` | `matchFound(candidateConsumers, networkConsumers)` — inner `candidateConsumers.contains()` loop; `networkConsumers` is typically 1–2 consumer IDs per subscription; O(S×C) where C≈1 | CLEAN (bounded) |
|
||
| `network/DemandForwardingBridgeSupport.java` | `contains(BrokerId[], BrokerId)` | Linear scan over `brokerPath` array — called on every routed message; `brokerPath` is the number of broker hops, bounded by network diameter (typically ≤ 10) | CLEAN (bounded) |
|
||
| `broker/region/Queue.java` | `doPageInForDispatch()` | `pagedInMessages.contains(ref)` inside loop over `result` — `OrderedPendingList.contains()` uses a `HashMap<MessageId, PendingNode>`; O(1) lookup | CLEAN (HashMap) |
|
||
| `broker/region/Queue.java` | `doDispatch()` | `dispatchPendingList.contains(qmr)` inside loop — `QueueDispatchPendingList` delegates to `OrderedPendingList` with `HashMap`; O(1) | CLEAN (HashMap) |
|
||
| `broker/region/Queue.java` | `doActualDispatch()` | `fullConsumers.contains(s)` — `fullConsumers` is a `HashSet<Subscription>`; O(1) | CLEAN (HashSet) |
|
||
| `broker/BrokerService.java` | `getNetworkConnectorByName()` | Linear scan over `networkConnectors` list — admin/configuration lookup, not per-message | CLEAN (admin path) |
|
||
| `broker/TransportConnector.java` | `getThrowableList()` | `list.contains(throwable)` in `while (throwable != null ...)` — exception chain cycle detection; error path, chain depth bounded in practice (< 20) | CLEAN (error path, bounded) |
|
||
|
||
## Summary
|
||
|
||
ActiveMQ's hot message dispatch path (`Queue.java`) uses `OrderedPendingList` which
|
||
wraps a `HashMap` for O(1) `contains()` checks. The network bridge destination filter
|
||
lists are configuration-time and small. Broker path dedup in
|
||
`DemandForwardingBridgeSupport` is bounded by network diameter. No production hot-path
|
||
O(N²) patterns found beyond the consumer dedup already patched in `activemq-0001`.
|