CVE-2026-41846

Cross-Site Scripting
Affects
Spring Framework
in
Spring
No items found.
Versions
>=4.3.0 <=4.3.30, >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, >=7.0.0 <=7.0.7
Exclamation circle icon
Patch Available

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

Overview

Spring Framework is the foundational application framework for the Java platform, providing dependency injection, data access, transaction management, and the Spring MVC web stack. Spring MVC ships a JSP tag library, the spring-form tags (the form:form, form:input, form:select, and other form:* tags), that renders HTML form controls bound to model attributes. Every common HTML attribute these tags emit, such as lang, title, and the various on* event handlers, is HTML-escaped before being written into the response so that bound or configured values cannot break out of the attribute context.

A medium-severity vulnerability (CVE-2026-41846) has been identified in that tag library. Three CSS-related attributes, cssClass, cssErrorClass, and cssStyle, were written to the rendered tag without the HTML-escaping that every other attribute received. A Spring MVC application that passes a user-supplied value into any of those attributes of a form:* tag therefore allows that value to break out of the attribute and inject arbitrary HTML or JavaScript, resulting in a reflected cross-site scripting condition.

Per OWASP, Cross-Site Scripting (XSS) attacks are a type of injection in which malicious scripts are injected into otherwise benign and trusted websites; they occur anywhere a web application uses input from a user within the output it generates without validating or encoding it. Here the unencoded output is the class or style attribute of a form control: an attacker who can influence the value bound into cssClass, cssErrorClass, or cssStyle can terminate the attribute and the tag and inject a script-bearing element that executes in the victim's browser in the application's origin.

The CVSS v3.1 base score for this vulnerability is 5.3 (Medium) with vector AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N. The attack vector is Network and no privileges are required, but attack complexity is High and user interaction is Required because the attacker must induce the victim to load a page that reflects the attacker-influenced CSS attribute. The impact is scoped Confidentiality High and Integrity Low, reflecting script execution in the victim's session; there is no availability impact.

This issue affects Spring Framework >=4.3.0 <=4.3.30, >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, and >=7.0.0 <=7.0.7.

Details

Module Info

Vulnerability Info

The vulnerability is in AbstractHtmlElementTag in the spring-webmvc module, the base class for the spring-form JSP tags under org.springframework.web.servlet.tags.form. Its writeOptionalAttributes(TagWriter) method emits the common HTML attributes shared by every form:* tag. Most attributes are written through the writeOptionalAttribute(tagWriter, name, value) helper, which calls getDisplayString(...) and therefore HTML-escapes the value by default. The three CSS attributes did not use that path.

Pre-fix, cssStyle was written with the raw writeOptionalAttributeValue call, and cssClass and cssErrorClass were resolved through resolveCssClass(), which returned a value produced by ObjectUtils.getDisplayString(...). ObjectUtils.getDisplayString only null-checks and calls toString(); it performs no HTML escaping:

protected void writeOptionalAttributes(TagWriter tagWriter) throws JspException {
    tagWriter.writeOptionalAttributeValue(CLASS_ATTRIBUTE, resolveCssClass());
    tagWriter.writeOptionalAttributeValue(STYLE_ATTRIBUTE,
            ObjectUtils.getDisplayString(evaluate("cssStyle", getCssStyle())));
    writeOptionalAttribute(tagWriter, LANG_ATTRIBUTE, getLang());
    // ... every other attribute uses the escaping helper ...
}

protected String resolveCssClass() throws JspException {
    if (getBindStatus().isError() && StringUtils.hasText(getCssErrorClass())) {
        return ObjectUtils.getDisplayString(evaluate("cssErrorClass", getCssErrorClass()));
    }
    else {
        return ObjectUtils.getDisplayString(evaluate("cssClass", getCssClass()));
    }
}


The value then flows into TagWriter, whose writeAttribute appends it verbatim into the response with no encoding, so a cssClass value that begins by closing the quote and the opening tag (a quote, an angle bracket, and then an injected script element) closes the class attribute and the tag and injects an executing element. FormTag overrides resolveCssClass() with the same non-escaping call, so the form:form tag itself is affected in addition to the bound input tags.

The fix routes the CSS attributes through the same escaping path as every other attribute. resolveCssClass() now calls the inherited getDisplayString(...) (which escapes when HTML escaping is enabled, the default for spring-form tags), and cssStyle is written through the writeOptionalAttribute(...) helper. The now-unused org.springframework.util.ObjectUtils import is removed. Control flow and the public tag API are unchanged:

protected void writeOptionalAttributes(TagWriter tagWriter) throws JspException {
    tagWriter.writeOptionalAttributeValue(CLASS_ATTRIBUTE, resolveCssClass());
    writeOptionalAttribute(tagWriter, STYLE_ATTRIBUTE, getCssStyle());
    writeOptionalAttribute(tagWriter, LANG_ATTRIBUTE, getLang());
    // ...
}

protected String resolveCssClass() throws JspException {
    if (getBindStatus().isError() && StringUtils.hasText(getCssErrorClass())) {
        return getDisplayString(evaluate("cssErrorClass", getCssErrorClass()));
    }
    else {
        return getDisplayString(evaluate("cssClass", getCssClass()));
    }
}


The same one-line change is applied to FormTag.resolveCssClass(). The fix is delivered in upstream commit e8f10244e385 ("Ensure consistent JSP tag attribute processing", Closes gh-36797) on main for the 7.0.8 release, with the identical change shipping as 1829b42b9c45 on the 6.2.x branch for the 6.2.19 release.

These CSS attributes and the non-escaping ObjectUtils.getDisplayString(...) treatment have been part of the spring-form tag library since Spring 2.0; AbstractHtmlElementTag and FormTag are both annotated @since 2.0. The vulnerable code is present unchanged across the 4.3.x, 5.3.x, and 6.1.x lines. The advisory's listed floor of 5.3.x reflects only Spring's currently-supported scope; older lines, including the lines covered by NES support, are also affected.

Steps To Reproduce

1. In a Spring MVC application that uses JSP views with the spring-form tag library, bind a model attribute or request parameter into the cssClass (or cssErrorClass or cssStyle) attribute of a form:* tag. For example, in a JSP:

   <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
   <form:form modelAttribute="user">
       <form:input path="name" cssClass="${param.theme}"/>
   </form:form>

Here the theme request parameter is reflected into the class attribute of the rendered input.

2. Request the page with a payload in the reflected parameter that breaks out of the attribute and the tag, that is, a value that begins by closing the quote and the opening tag and then supplies an injected script element (URL-encoded in the query string).

3. Observe the rendered HTML. On an affected version the value is emitted unescaped, producing a live, executing script element injected after the input tag; the injected script runs in the victim's browser in the application's origin.

4. After upgrading to a fixed version (Spring Framework 6.2.19, 7.0.8, or a HeroDevs NES build), repeat the request. The value is now HTML-escaped and rendered inert inside the class attribute (the angle brackets and quotes appear as their entity encodings rather than as markup).

Mitigation

Only recent versions of Spring Framework receive community support and updates. Older versions, including the 4.3.x, 5.3.x, and 6.1.x lines, have no publicly available open-source fix for this vulnerability.

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

  • Upgrade to a currently supported open-source version of Spring Framework that contains the fix. The OSS fix ships in Spring Framework 6.2.19 (6.2.x line) and 7.0.8 (7.0.x line).
  • As an interim hardening step, ensure no user-controlled value is bound into the cssClass, cssErrorClass, or cssStyle attributes of any form:* tag, and validate or allow-list any value that reaches those attributes.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Spring Framework.
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2026-41846
PROJECT Affected
Spring Framework
Versions Affected
>=4.3.0 <=4.3.30, >=5.3.0 <=5.3.48, >=6.1.0 <=6.1.27, >=6.2.0 <=6.2.18, >=7.0.0 <=7.0.7
NES Versions Affected
Published date
June 11, 2026
≈ Fix date
June 10, 2026
Category
Cross-Site Scripting
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 clicking “submit” 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.