CVE-2026-47861
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Integration extends the Spring programming model to support the well-known Enterprise Integration Patterns, providing message channels, endpoints, transformers, and channel adapters that let Spring applications exchange data with external systems over protocols such as HTTP, JMS, AMQP, TCP/UDP, syslog, and the file system.
A Server-Side Request Forgery (SSRF) vulnerability (CVE-2026-47861) has been identified in the UDP inbound channel adapter of Spring Integration, which allows unauthenticated attackers to make the listening application emit a UDP datagram to any internal or external host and port they choose. Per OWASP: In a Server-Side Request Forgery (SSRF) attack, the attacker can abuse functionality on the server to read or update internal resources. In this case the tampered value is not a URL but an acknowledgment address: the UDP inbound channel adapter reads a host and port out of the body of an inbound datagram, carries them in the IpHeaders.ACK_ADDRESS message header, and sends its acknowledgment datagram to whatever that header names, with no check that the destination has any relationship to the packet's sender.
This issue affects the UDP inbound adapter support of Spring Integration.
Details
Module Info
- Product: Spring Integration
- Affected packages:
org.springframework.integration:spring-integration-ip - Affected versions: >= 2.0.0 <= 5.5.21, >= 6.0.0 <= 6.4.12, >= 6.5.0 <= 6.5.10, >= 7.0.0 < 7.0.6, >= 7.1.0 < 7.1.1
- GitHub repository: https://github.com/spring-projects/spring-integration
- Published packages: https://central.sonatype.com/artifact/org.springframework.integration/spring-integration-ip
- Package manager: Maven
- Fixed in:
- NES for Spring Integration lines 5.5.x, 6.2.x, 6.3.x, 6.4.x and 6.5.x
- OSS Spring Integration 7.0.6 and 7.1.1
Vulnerability Info
This Medium-severity vulnerability is found in the org.springframework.integration:spring-integration-ip package in the UDP inbound adapter support of Spring Integration. The datagram mapper deliberately peeked into the packet body for an acknowledgment prefix even when the adapter had not been configured to acknowledge anything, and lifted the acknowledgment address out of the payload into a message header:
int port = packet.getPort();
// Peek at the message in case they didn't configure us for ack but the sending
// side expects it.
if (this.acknowledge || startsWith(buffer, IpHeaders.ACK_ADDRESS)) {
try {
String headersString = new String(packet.getData(), offset, length, this.charset);
Matcher matcher = UDP_HEADERS_PATTERN.matcher(headersString);
if (matcher.find()) {
...
message = getMessageBuilderFactory().withPayload(payload)
.setHeader(IpHeaders.ACK_ID, UUID.fromString(matcher.group(2)))
.setHeader(IpHeaders.ACK_ADDRESS, matcher.group(1))
...
.build();
}
}
...
}
The receiving adapter then decoded that header and sent the datagram wherever it pointed, with no check that the destination had anything to do with the sender:
protected void sendAck(Message<byte[]> message) {
MessageHeaders headers = message.getHeaders();
Object id = headers.get(IpHeaders.ACK_ID);
...
String ackAddress = headers.get(IpHeaders.ACK_ADDRESS, String.class).trim();
Matcher mat = ADDRESS_PATTERN.matcher(ackAddress);
if (!mat.matches()) {
throw new MessagingException(message,
"Ack requested but could not decode acknowledgment address: " + ackAddress);
}
String host = mat.group(1);
int port = Integer.parseInt(mat.group(2));
InetSocketAddress whereTo = new InetSocketAddress(host, port);
...
}
The exposure is unconditional rather than a consequence of misconfiguration. The UDP inbound channel adapter exposes no way to turn acknowledgments on: there is no acknowledge attribute on the udp-inbound-channel-adapter namespace element, no setter on the adapter, and no Java DSL method, so the acknowledge flag guarding the first branch is always false. The payload peek is therefore the only code path that can ever produce an acknowledgment, and every UDP inbound channel adapter is affected in its default configuration. Because the peek runs regardless of the configured acknowledge flag, a single unauthenticated packet carrying a crafted acknowledgment prefix is enough to steer the outbound datagram. The attacker controls both the host and the port, which makes the adapter usable for blind UDP probing of internal networks, for poking UDP services such as memcached, SNMP, or NTP that are not reachable from outside, and as a reflection hop.
This vulnerability was introduced in 2010 with Spring Integration 2.0.0.
Mitigation
Only recent versions of Spring Integration receive community support. Older lines are End-of-Life and will not receive public updates to address this issue.
Applying a fixed version changes UDP acknowledgment behavior, and the change is silent. Acknowledgments are no longer sent automatically in response to an acknowledgment prefix in the packet body, so a sender that relied on receiving one will simply stop receiving it, with no error raised on either side. Acknowledgments are now opt-in and restricted to destinations an operator has named in advance, through the trusted-ack-addresses namespace attribute, the setTrustedAckAddresses method on the receiving adapter, or the trustedAckAddresses Java DSL method. Patterns are matched against the full host:port value and support wildcards, for example 192.168.1.*:*. Once trusted patterns are configured, a packet whose acknowledgment address does not match one of them is rejected and is not delivered to the channel.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Integration. The open-source fix ships in Spring Integration 7.0.6 on the 7.0.x line and 7.1.1 on the 7.1.x line.
- Do not treat leaving the adapter's acknowledge flag off as a mitigation. The mapper peeks for an acknowledgment prefix regardless of how acknowledge is configured, so an adapter that was never configured to acknowledge anything can still be made to emit the datagram.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.