CVE-2026-59313
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Spring Framework is a widely used application framework for the Java platform that provides the core programming and configuration model for modern Java enterprise applications, including the Spring MVC servlet web stack. Alongside annotated controllers, Spring MVC offers a functional programming model, WebMvc.fn, in which routes are declared as functions that return a ServerResponse. Since Spring Framework 5.3.2 a functional route can return ServerResponse.sse(...) to stream Server-Sent Events (SSE), a line-oriented text protocol in which each event is made up of id:, event:, data: and comment lines terminated by a blank line.
A content spoofing vulnerability (CVE-2026-59313) has been identified in the SSE support of the Spring MVC functional web framework, which allows attackers to corrupt the event stream delivered to other users of the application. When plain-text data that an attacker controls is sent through an SSE ServerResponse and contains a bare carriage return, the text breaks out of its data: field and the remainder is interpreted by the browser as new SSE fields. Depending on the frontend application logic, this can corrupt client-side state or present malicious information to other users.
Per OWASP: Content spoofing, also referred to as content injection, "arbitrary text injection" or virtual defacement, is an attack targeting a user made possible by an injection vulnerability in a web application. When an application does not properly handle user-supplied data, an attacker can supply content to a web application, typically via a parameter value, that is reflected back to the user.
The advisory rates this vulnerability Low severity with the CVSS v3.1 vector AV:N/AC:H/PR:L/UI:R/S:U/C:N/I:L/A:N, which corresponds to a base score of 2.6. The attack vector is Network, attack complexity is High because the application must stream SSE through the functional web framework with plain-text rather than JSON payloads and the attacker's text must reach other users' streams unchanged, Low privileges are required because the attacker needs to be able to submit data that the application streams to other users, user interaction is Required because the victims must be connected to the stream, and the impact is Integrity-only and Low because the consequence is injected or corrupted event data in other users' streams rather than access to data held by the application.
This issue affects Spring Framework >=5.3.0 <=5.3.49, >=6.0.0 <=6.0.30, >=6.1.0 <=6.1.28, >=6.2.0 <=6.2.19, and >=7.0.0 <=7.0.8, including the End-of-Life 5.3.x, 6.1.x, and 6.2.x lines supported by NES for Spring Framework.
Details
Module Info
- Product: Spring Framework
- Affected packages:
org.springframework:spring-webmvc - Affected versions: >=5.3.0 <=5.3.49, >=6.0.0 <=6.0.30, >=6.1.0 <=6.1.28, >=6.2.0 <=6.2.19, >=7.0.0 <=7.0.8
- GitHub repository: https://github.com/spring-projects/spring-framework
- Published packages: https://central.sonatype.com/artifact/org.springframework/spring-webmvc
- Package manager: Maven
- Fixed in:
- NES for Spring Framework nes-v5.3.54, nes-v6.1.30, and nes-v6.2.21
- Spring Framework 7.0.9 (OSS)
Vulnerability Info
This Low-severity vulnerability is found in the spring-webmvc package in multiple versions of Spring Framework, and is reached only by applications that use the WebMvc.fn functional web framework to stream Server-Sent Events. That means a router function whose handler returns ServerResponse.sse(sseBuilder -> ...) and whose SseBuilder callback passes plain-text values derived from another user's input, such as chat messages, display names or notifications, to send(String), data(String), comment(String), id(String) or event(String). Events sent as objects are serialized to JSON by an HttpMessageConverter, which escapes line terminators inside strings, so that path is not affected. Annotated controllers that return an SseEmitter, and the Spring WebFlux ServerSentEvent writer, are separate code paths that already escape carriage returns and are likewise not affected.
The SSE wire format terminates a line on a line feed, a carriage return, or the two together, so a value that spans several lines must have every line prefixed with its field name for the browser to reassemble it as one field. The DefaultSseBuilder implementation behind ServerResponse.sse(...) only splits on the line feed when it writes data: and comment lines, and writes id: and event: values verbatim:
@Override
public SseBuilder id(String id) {
Assert.hasLength(id, "Id must not be empty");
return field("id", id);
}
@Override
public SseBuilder event(String eventName) {
Assert.hasLength(eventName, "Name must not be empty");
return field("event", eventName);
}
@Override
public SseBuilder comment(String comment) {
String[] lines = comment.split("\n");
for (String line : lines) {
field("", line);
}
return this;
}
private SseBuilder field(String name, String value) {
this.builder.append(name).append(':').append(value).append('\n');
return this;
}
private void writeString(String string) throws IOException {
String[] lines = string.split("\n");
for (String line : lines) {
field("data", line);
}
this.builder.append('\n');
...
}
A bare carriage return inside the value is left untouched. On the server the value is written as a single data: line, but the event source parser in every browser treats the carriage return as the end of that line, so whatever follows it is parsed as a fresh SSE field. An attacker who can get a value such as hello\revent:logout\rdata:{"forged":true}\r\r streamed to other users can therefore terminate the current event early and append their own event:, data:, id: or retry: lines, forging whole events or truncating legitimate ones in the stream that every connected user receives. The same effect is possible through id(String) and event(String) if the application derives those values from user input, because neither method rejects line terminators.
This vulnerability was introduced in 2020 with Spring Framework 5.3.2.
Mitigation
Only recent versions of Spring Framework receive community support. The 5.3.x, 6.1.x, and 6.2.x lines are End-of-Life and will not receive public updates to address this issue, so there is no publicly available fix for those lines other than through a commercial support partner.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Spring Framework. The open-source fix ships in Spring Framework 7.0.9 on the 7.0.x line.
- Leverage a commercial support partner like HeroDevs for post-EOL security support, which provides the fix for the 5.3.x, 6.1.x, and 6.2.x lines in nes-v5.3.54, nes-v6.1.30, and nes-v6.2.21.
Credits
- This issue was discovered internally by the Spring team and later reported independently by an external researcher.
- Arpit Jain (finder)