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:

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:

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.

Comments

Charlie Arehart

That's wonderful, Pete. Thanks for doing it. I had started on a similar post a couple of weeks ago (when I saw the matter come up in some online forums), and I'd gotten about 80% done then lost track. You hit all the bases (or so it seems to me), to help (hopefully) calm people about this matter. Again, thanks for the effort!