CVE-2026-59305
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Cloud Stream is a framework for building message-driven microservices on top of Spring Boot and Spring Integration. It provides a binder abstraction that connects application code to messaging middleware such as RabbitMQ, Apache Kafka and Apache Pulsar, so the same business logic can run against different brokers without being rewritten.
A denial of service vulnerability (CVE-2026-59305) has been identified in Spring Cloud Stream function support, which allows attackers who can drive repeated sends to a partitioned dynamic destination to accumulate channel interceptors without limit, degrading throughput and eventually exhausting heap.
Per OWASP: The Denial of Service (DoS) attack is focused on making a resource (site, application, server) unavailable for the purpose it was designed.
This issue affects multiple versions of Spring Cloud Stream, beginning with the release that added destination and key extraction for the send-to header.
Details
Module Info
- Product: Spring Cloud Stream
- Affected packages:
org.springframework.cloud:spring-cloud-stream - Affected versions: >=4.0.4 <=4.0.5, >=4.1.0 <=4.1.6, >=4.2.0 <=4.2.3, >=4.3.0 <=4.3.3, >=5.0.0 <5.0.3
- GitHub repository: https://github.com/spring-cloud/spring-cloud-stream
- Published packages: https://central.sonatype.com/artifact/org.springframework.cloud/spring-cloud-stream
- Package manager: Maven
- Fixed in: NES for Spring Cloud Stream v4.1.9, v4.2.6 and v4.3.5
Vulnerability Info
This Low-severity vulnerability is found in the spring-cloud-stream package in multiple versions of Spring Cloud Stream. When a function result carries a spring.cloud.stream.sendto.destination header, FunctionConfiguration resolves the named output channel and, if that destination's producer binding is partitioned, attaches a DefaultPartitioningInterceptor to it. The attachment happens on the send path with no check for an interceptor that is already present:
if (sendToBindingProducerProperties != null && sendToBindingProducerProperties.isPartitioned()) {
((AbstractMessageChannel) outputChannel)
.addInterceptor(new DefaultPartitioningInterceptor(bindingProperties, applicationContext.getBeanFactory()));
}
The resolved channel is cached and reused across sends, so the guard is the only thing that would prevent duplication, and there is none. Each message routed to the same partitioned dynamic destination appends another interceptor to the same channel. The interceptor list is walked for every message, so the per-message cost grows linearly with the number of sends already performed, and the retained interceptors are never released for the lifetime of the channel. A sustained stream of sends to one partitioned destination therefore degrades throughput progressively and ends in heap exhaustion.
Exploitation is constrained: the attacker needs the privileges required to trigger the function and influence the send-to destination header, the target binding must be configured as partitioned, and the vendor score is CVSS 3.1 3.1 (AV:N/AC:H/PR:H/UI:R/S:U/C:L/I:L/A:N).
This vulnerability was introduced in 2023 with Spring Cloud Stream 4.0.4.
Mitigation
Only recent versions of Spring Cloud Stream receive community support. Older lines are End-of-Life and will not receive public updates to address this issue.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Cloud Stream.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
Credits
- No finder has been publicly credited for this issue.