CVE-2026-59321
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-59321) has been identified in AbstractScriptExecutor, the base class of the JSR-223 script executors, which allows one message's payload and header bindings to leak into the script evaluation performed for another message when the configured engine is not thread-safe.
Under CWE-488: The product does not sufficiently enforce boundaries between the states of different sessions, causing data to be provided to, or used by, the wrong session.
This issue affects the JSR-223 scripting support of Spring Integration.
Details
Module Info
- Product: Spring Integration
- Affected packages:
org.springframework.integration:spring-integration-scripting - Affected versions: >=7.1.0 <7.1.1, >=7.0.0 <7.0.6, >=2.2.1 <=6.5.10
- GitHub repository: https://github.com/spring-projects/spring-integration
- Published packages: https://central.sonatype.com/artifact/org.springframework.integration/spring-integration-scripting
- Package manager: Maven
- Fixed in:
- NES for Spring Integration: 5.5.x, 6.2.x, 6.3.x, 6.4.x, 6.5.x
- OSS Spring Integration 7.0.6, 7.1.1
Vulnerability Info
This Medium-severity vulnerability is found in the org.springframework.integration:spring-integration-scripting package in the JSR-223 scripting support of Spring Integration.
A script-backed endpoint creates one ScriptExecutor and keeps it for the lifetime of the flow. The executor resolves a single ScriptEngine once, in its constructor, and every message that reaches the endpoint is evaluated on that shared instance with no serialization of access:
private final ScriptEngine scriptEngine;
protected AbstractScriptExecutor(String language) {
Assert.hasText(language, "language must not be empty");
this.scriptEngine = new ScriptEngineManager().getEngineByName(language);
Assert.notNull(this.scriptEngine, () -> invalidLanguageMessage(language));
...
}
@Override
public Object executeScript(ScriptSource scriptSource, Map<String, Object> variables) {
try {
Object result;
String script = scriptSource.getScriptAsString();
...
Bindings bindings = null;
if (variables != null && !variables.isEmpty()) {
bindings = new SimpleBindings(variables);
result = this.scriptEngine.eval(script, bindings);
}
else {
result = this.scriptEngine.eval(script);
}
...
}
catch (Exception e) {
throw new ScriptingException(e.getMessage(), e);
}
}
JSR-223 states that an engine whose factory returns null for the THREADING parameter must not be used from more than one thread at a time; the Kotlin kts engine is one such engine. The executor never reads that parameter, so when messages arrive concurrently, for example on a queue channel with a task executor or on a multi-threaded inbound gateway, two evaluations enter the same engine at once and corrupt its internal state. The practical consequences are that bindings established for one message, including its payload and headers, are visible to the script running for another message, and that spurious script exceptions surface on unrelated flows.
This vulnerability was introduced in 2013 with Spring Integration 2.2.1, when the executor stopped creating an engine per execution and began reusing a single shared instance.
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.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Integration.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.