CVE-2026-59324

Information Exposure
Affects
Spring Integration
in
Spring
No items found.
Versions
>=7.1.0 <7.1.1, >=7.0.0 <7.0.6, >=5.1.0 <=6.5.10
Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Spring Integration is the Spring portfolio project that brings the Enterprise Integration Patterns to Spring applications. It provides a lightweight messaging framework of channels, endpoints, transformers and routers, together with channel adapters for protocols and technologies such as files, FTP, HTTP, JDBC, JMS, AMQP, SMB and ZeroMQ.

An Information Exposure vulnerability (CVE-2026-59324) has been identified in the fluxTransform() operator of the Java DSL, which allows one user's response payload to be delivered to another user's reply channel when the supplied function is asynchronous or reorders elements.

Per OWASP, such failures "typically lead to unauthorized information disclosure" or modification of data beyond a user's limits. Both happen here with no permission check involved — the framework's own header handling carries one user's response across the boundary, producing what the advisory calls "cross-request information disclosure and reply mis-routing." The CVSS v3.1 base score for this vulnerability is 8.2 (High) with vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N.

This issue affects the reactive Java DSL of Spring Integration. A deployment is exposed only if a flow calls fluxTransform() with a function that emits raw payloads instead of Message instances, and that function is asynchronous, concurrent, or reorders elements — for example a flatMap over a remote call. A function that emits Message instances itself is unaffected, and so is a synchronous one-in-one-out function, because the shared holder is then always read in the same order it was written.

Details

Module Info

Vulnerability Info

The vulnerability is in Transformers and BaseIntegrationFlowDefinition in the spring-integration-core Java DSL. BaseIntegrationFlowDefinition.fluxTransform() is the public entry point: it accepts a function that may emit plain payloads instead of Message instances, and delegates to the package-private helper Transformers.transformWithFunction(), where the defect lives. To rebuild a reply for a raw payload, that helper must know which request the payload came from, and it tracks that in a single holder placed in the Reactor context:

static <I, O> Flux<Message<O>> transformWithFunction(
    Publisher<Message<I>> publisher,
    Function<? super Flux<Message<I>>, ? extends Publisher<O>> fluxFunction) {

  return Flux.from(publisher)
      .flatMap(
          message ->
              Mono.deferContextual(
                  ctx -> {
                    ctx.get(RequestMessageHolder.class).set(message);
                    return Mono.just(message);
                  }))
      .transform(fluxFunction)
      .flatMap(
          data ->
              data instanceof Message<?>
                  ? Mono.just((Message<O>) data)
                  : Mono.deferContextual(
                          ctx -> Mono.just(ctx.get(RequestMessageHolder.class).get()))
                      .map(
                          requestMessage ->
                              MessageBuilder.withPayload(data)
                                  .copyHeaders(requestMessage.getHeaders())
                                  .build()))
      .contextWrite(ctx -> ctx.put(RequestMessageHolder.class, new RequestMessageHolder()));
}

private static final class RequestMessageHolder extends AtomicReference<Message<?>> {
  
}

The Reactor context is established once per subscription, not once per element, so a single RequestMessageHolder is shared by every message flowing through the same FluxMessageChannel subscription. Each inbound message overwrites it, and the downstream stage reads whatever value happens to be there when a payload arrives. As soon as the user function is asynchronous, concurrent or reordering, for example a flatMap over a remote call, the reply is built with copyHeaders() from a different in-flight request, so replyChannel, errorChannel, correlationId and any propagated security or tenant headers belong to another user. The response is then delivered to that other user's reply channel, which discloses the payload across requests and mis-routes the exchange.

This vulnerability was introduced in 2018 with Spring Integration 5.1.0, when the fluxTransform() operator was added to the Java DSL.

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.

Note that the fix changes behaviour rather than restoring it: fluxTransform() no longer infers which request a raw payload belongs to, and instead throws IllegalStateException for any element the supplied function emits that is not already a Message. Applications whose function emits bare payloads must be updated to emit Message instances, as in the first mitigation below.

Users of the affected components should apply one of the following mitigations:

  • Declare the fluxTransform() function as Function<? super Flux<Message<I>>, ? extends Publisher<Message<O>>> so that it emits messages itself and no reply headers are copied from an unrelated request.
  • Upgrade to a currently supported version of Spring Integration.
  • 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
High
ID
CVE-2026-59324
PROJECT Affected
Spring Integration
Versions Affected
>=7.1.0 <7.1.1, >=7.0.0 <7.0.6, >=5.1.0 <=6.5.10
NES Versions Affected
Published date
August 21, 2026
≈ Fix date
Category
Information Exposure
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.