Understanding and Checking for Tomcat CVE-2025-24813
By Pete Freitag

I've had a few questions lately about the Tomcat vulnerability CVE-2025-24813. There are two potential issues at hand, but according to the CVE both vulnerable cases have the requirement:
"writes enabled for the default servlet (disabled by default)"
Since "writes enabled for the default servlet" is the key requirement for the vulnerability, let's take a minute and understand what is the default servlet, and how might writes be enabled for it.
Let's also not miss "disabled by default", in the CVE description which indicates that writes are not enabled by default in Tomcat. I think the confusion may arise because we are talking about the Default Servlet, and a non default value of the default servlet (phew!). We have double negation, and double implication of the word default going on, so it can be confusing. Hopefully if you continue reading, I can clarify this.
What is the Tomcat Default Servlet?
The Default Servlet, is implemented in the class org.apache.catalina.servlets.DefaultServlet
, it is typically used for serving static files, or providing directory listings on the tomcat web server.
Here's an example of the default servlet configuration, found in the web.xml
file:
<servlet> <servlet-name>default</servlet-name> <servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1<load-on-startup> </servlet>
How can I see if writes are enabled for the default servlet?
Locate all web.xml files (you may have more than one), look for the DefaultServlet, and then check for an init-param
with the param-name
of readonly
, if it is set to false
then it is write enabled.
Example of a Write Enabled Default Servlet
<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> </init-param> <load-on-startup>1<load-on-startup> </servlet>
What if I don't have <init-param>readonly</init-param>
in my web.xml?
The default value of the readonly param is true, according to Tomcat's docs, and the CVE itself. That means that writes are not enabled, if the readonly param is missing from the servlet configuration. Make sure you have checked all web.xml files, you may have more than one.
Conditions Required for Information Disclosure / Injecting Content into Files
According to the CVE, If all of the following were true, a malicious user was able to view security sensitive files and/or inject content into those files:
- writes enabled for the default servlet (disabled by default, see above)
- support for partial PUT (enabled by default)
- a target URL for security sensitive uploads that was a sub-directory of a target URL for public uploads
- attacker knowledge of the names of security sensitive files being uploaded
- the security sensitive files also being uploaded via partial PUT
Conditions Required for RCE
According to the CVE, If all of the following were true, a malicious user was able to perform remote code execution:
- writes enabled for the default servlet (disabled by default)
- support for partial PUT (enabled by default)
- application was using Tomcat's file based session persistence with the default storage location
- application included a library that may be leveraged in a deserialization attack
So in conclusion, you need to have the readonly init-param explicitly set to false in your web.xml Tomcat configuration to have writes enabled for the default servlet, and most installations will not have writes enabled.
Understanding and Checking for Tomcat CVE-2025-24813 was first published on March 17, 2025.
Weekly Security Advisories Email
Advisory Week is a new weekly email containing security advisories published by major software vendors (Adobe, Apple, Microsoft, etc).