CVE-2026-47861

Server-Side Request Forgery
Affects
Spring Integration
in
Spring
No items found.
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
Exclamation circle icon
Patch Available

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

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.
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2026-47861
PROJECT Affected
Spring Integration
Versions Affected
>= 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
NES Versions Affected
Published date
August 29, 2026
≈ Fix date
August 28, 2026
Category
Server-Side Request Forgery
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Spring
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.