CVE-2026-59299

Information Exposure
Affects
Spring Cloud Function
in
Spring
No items found.
Versions
>=3.1.0 <=4.1.6, >=4.2.0 <=4.2.7, >=4.3.0 <=4.3.4, >=5.0.0 <5.0.4
Exclamation circle icon
Patch Available

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

Overview

Spring Cloud Function is the Spring project that lets developers express business logic as plain Java functions (Function, Supplier and Consumer) and run that same logic across web endpoints, messaging middleware such as Apache Kafka and RabbitMQ, and serverless platforms such as AWS Lambda, without binding the code to any one runtime. Its function catalog registers every function under a name and resolves a requested function definition on lookup, including composed definitions written with a pipe separator such as uppercase|reverse.

An Information Exposure vulnerability (CVE-2026-59299) has been identified in the function catalog implementation, which allows attackers who can cause a composed function definition to be resolved to poison the catalog entry of a standalone function, so that unrelated callers of that function receive a shared wrapper whose output conversion has been disabled and which therefore returns unconverted internal payload representations to consumers that expect a negotiated content type.

Per OWASP: Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification, or destruction of all data or performing a business function outside the user's limits.

This issue affects the function catalog and function composition handling of Spring Cloud Function.

Details

Module Info

Vulnerability Info

This Low-severity vulnerability is found in the org.springframework.cloud:spring-cloud-function-context package in the function catalog of Spring Cloud Function.

Function lookups are served from a single process-wide cache keyed by function definition. When the requested definition is not already cached, the registry builds it by walking the pipe-separated names of the definition and folding each resolved function into an accumulating composition:

<T> T doLookup(Class<?> type, String functionDefinition, String[] expectedOutputMimeTypes) {
    FunctionInvocationWrapper function = this.wrappedFunctionDefinitions.get(functionDefinition);
    if (function == null) {
        function = this.compose(type, functionDefinition);
    }
    ...
}

private FunctionInvocationWrapper compose(Class<?> type, String functionDefinition) {
    String[] functionNames = StringUtils.delimitedListToStringArray(functionDefinition.replaceAll(",", "|").trim(), "|");
    FunctionInvocationWrapper composedFunction = null;

    for (String functionName : functionNames) {
        FunctionInvocationWrapper function = this.findFunctionInFunctionRegistrations(functionName);
        if (function == null) {
            return null;
        }
        else {
            if (composedFunction == null) {
                composedFunction = function;
            }
            else {
                FunctionInvocationWrapper andThenFunction =
                        invocationWrapperInstance(functionName, function.getTarget(), function.inputType, function.outputType);
                composedFunction = (FunctionInvocationWrapper) composedFunction.andThen((Function<Object, Object>) andThenFunction);
            }
            composedFunction = this.enrichInputIfNecessary(composedFunction);
            composedFunction = this.enrichOutputIfNecessary(composedFunction);
            if (composedFunction.isSingleton) {
                this.wrappedFunctionDefinitions.put(composedFunction.functionDefinition, composedFunction);
            }
        }
    }
    return composedFunction;
}

The cache write sits inside the loop, so every intermediate state of the accumulator is published to the shared cache under its own name, not just the completed composition. Resolving a definition such as uppercase|reverse therefore also stores, under the plain name uppercase, the specific wrapper instance that was created to serve as the left-hand side of that composition. Any later lookup of the standalone function receives that shared instance rather than a wrapper built for its own use, which is enough on its own to leak per-composition state such as the expected output content type across otherwise unrelated invocations.

On the 4.x and 5.x lines the consequence is more direct, because composition mutates the left-hand wrapper in place while wiring the chain together:

this.setSkipOutputConversion(true);
((FunctionInvocationWrapper) after).setSkipOutputConversion(true);
Function rawComposedFunction = v -> ((FunctionInvocationWrapper) after).doApply(doApply(v));

Skipping output conversion is correct for a stage in the middle of a chain, whose result is fed to the next stage rather than serialized. Because the mutated receiver is also the object cached under the base function name, a subsequent lookup of that base function returns a wrapper that silently bypasses the configured output message conversion, so the caller receives the raw internal object representation instead of the negotiated, converted payload. On the 3.1.x and 3.2.x lines composition builds a fresh wrapper instead of mutating its receiver, so those lines carry only the shared-instance half of the flaw. An attacker who can influence which function definitions an application resolves, for example through a web or messaging endpoint that accepts a function definition name, can use a composed lookup to place a base function into this state for every other consumer of the same registry.

This vulnerability was introduced in 2020 with Spring Cloud Function 3.1.0.

Mitigation

Only recent versions of Spring Cloud Function 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 Function.
  • 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
Low
ID
CVE-2026-59299
PROJECT Affected
Spring Cloud Function
Versions Affected
>=3.1.0 <=4.1.6, >=4.2.0 <=4.2.7, >=4.3.0 <=4.3.4, >=5.0.0 <5.0.4
NES Versions Affected
Published date
September 2, 2026
≈ Fix date
September 1, 2026
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.