jstltomcat9

Apache Tomcat 9.0.96 JSTL c:out does no longer escape text and has inconsistent behavior


Since the 9.0.96 version of the Apache Tomcat servlet container released on 2024-10-08 the c:out tag behaves differently and looks like it's a potential security issue (code injection ?)

It looks like in certain circumstances it does no longer escape the value attribute.

Version 9.0.95 (and previous ones) does not have this behavior.

Here's how to reproduce the problem. Use a simple test file (use it as index.jsp in the ROOT webapp for instance, along with taglibs-standard-impl-1.2.5.jar and taglibs-standard-spec-1.2.5.jar in the app's lib folder) :

<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%
String test = "{ \"key\" : \"value\" }";
java.util.Map<String, String> map = new java.util.HashMap<>();
map.put("test", test);
request.setAttribute("test", test);
request.setAttribute("map", map);
%>
<!DOCTYPE html>
<html lang="en">
    <body>
    <input type="text" name="test" id="test" value="<c:out value="${test}" />" />
    <br/>
    <input type="text" name="test" id="test" value="<c:out value="<%=test %>" />" />
    <br/>
    <c:forEach items="${map}" var="entry">
        <input id="${entry.key}" name="${entry.key}" type="text" value="<c:out value="${entry.value}" />">
        <br/>
    </c:forEach>

    <br/>
    <br/>
    Tomcat Version : <%= application.getServerInfo() %>
    <br/>
    Servlet Specification Version : <%= application.getMajorVersion() %>.<%= application.getMinorVersion() %> 
    <br/>
    JSP version : <%=JspFactory.getDefaultFactory().getEngineInfo().getSpecificationVersion() %>
    </body>

</html>

In Tomcat 9.0.95 it renders like this (showing just the important part) :

<input type="text" name="test" id="test" value="{ &#034;key&#034; : &#034;value&#034; }" />
<input type="text" name="test" id="test" value="{ &#034;key&#034; : &#034;value&#034; }" />
<input id="test" name="test" type="text" value="{ &#034;key&#034; : &#034;value&#034; }">

enter image description here

In Tomcat 9.0.96 it renders like this :

<input type="text" name="test" id="test" value="{ &#034;key&#034; : &#034;value&#034; }" />
<input type="text" name="test" id="test" value="{ "key" : "value" }" />
<input id="test" name="test" type="text" value="{ "key" : "value" }">

enter image description here

Even worse, when refreshing the page (the above result is obtained only once, after the JSP is compiled), then it renders like this :

<input type="text" name="test" id="test" value="{ "key" : "value" }" />
<input type="text" name="test" id="test" value="{ "key" : "value" }" />
<input id="test" name="test" type="text" value="{ "key" : "value" }">

enter image description here


Solution

  • After more extensive research, the problem, not directly linked to the described behavior can be found here :

    https://bz.apache.org/bugzilla/show_bug.cgi?id=69399

    Probably it's best to avoid 9.0.96 until it's fixed.