Executive Summary

In March 2025, Apache disclosed CVE-2025-24813, a vulnerability impacting Apache Tomcat. This is a widely used platform that allows Apache web servers to run Java-based web applications. The flaw allows remote code execution, affecting Apache Tomcat versions 9.0.0.M1 to 9.0.98, 10.1.0-M1 to 10.1.34 and 11.0.0-M1 to 11.0.2.

The same month, Apache revealed two additional vulnerabilities in Apache Camel, a message routing middleware framework. These vulnerabilities are CVE-2025-27636 and CVE-2025-29891, two flaws that allow remote code execution, affecting Apache Camel versions 4.10.0 to 4.10.1, 4.8.0 to 4.8.4 and 3.10.0 to 3.22.3.

These vulnerabilities are significant because millions of developers rely on the platform provided by the Apache Foundation. Successful exploitation of these vulnerabilities can allow attackers to execute arbitrary code with Tomcat/Camel privileges.

Apache has released patches, and researchers quickly published proof‑of‑concept (PoC) exploits. Scans and probes for vulnerable servers were seen in the wild shortly after the disclosures. We have confirmed the potential for remote code execution from these three vulnerabilities.

Palo Alto Networks blocked 125,856 probes/scans/exploit attempts related to these vulnerabilities in March 2025. We advise organizations to apply patches promptly.

Palo Alto Networks customers are better protected through the following products and services:

If you think you might have been compromised or have an urgent matter, contact the Unit 42 Incident Response team.

CVE-2025-24813: Apache Tomcat

Vulnerability Overview

CVE-2025-24813 is a vulnerability in Apache Tomcat’s partial PUT feature that can allow attackers to overwrite serialized session files on disk, leading to arbitrary code execution.

This vulnerability arises when Tomcat is configured to persist HTTP session data, because unpatched Tomcat systems improperly handle partial PUT requests containing the Content-Range header.

Partial PUT

The term “partial PUT” refers to an HTTP PUT request that updates only part of a resource instead of replacing it entirely. When supported, partial PUT typically uses the Content-Range header in an HTTP request to specify which part of the resource should be modified.

This allows clients to upload or overwrite resource segments in chunks. Partial PUT can be exploited to perform incremental file uploads, overwrite specific parts of files, or bypass certain security checks if not properly handled.

Session Persistence Feature in Apache Tomcat

Apache Tomcat’s HTTP session manager includes a session persistence feature. This feature saves session data to a file or database when the server is shut down, and it reloads this cached data when the server is restarted. Session data contains information such as user login status and preferences, and this feature helps preserve a user’s session data across server restarts.

Tomcat encodes this saved session data as a stream of bytes using a process called serialization and stores the serialized data in the local file system. It serializes all session attributes stored in the HttpSession object. This includes any data your web application explicitly places in the session using session.setAttribute(). The information is typically stored somewhere under $TOMCAT_HOME/webapps/ROOT/.

However, the serialized session data is stored in the same directory used by Tomcat’s executePartialPut function. Users can craft HTTP requests to control the session ID and the filename of the cached data in this directory. This could allow an attacker to intentionally set the session ID to match the cached filename of malicious code previously saved to the cache. This can result in deserialization of the cached file, triggering the embedded malicious code.

Preconditions

The Content-Range header is often used with partial updates. This header indicates the request body contains a portion of the resource rather than the entire resource. If an HTTP PUT request contains a Content-Range header, Tomcat saves the content (body) of the PUT request to the cache location. The following code snippet shows that Tomcat saves the data from an HTTP PUT request that contains content.

A vulnerable Tomcat configuration must have two preconditions to exploit this vulnerability:

  1. A disabled readonly parameter in the Tomcat configuration file at $TOMCAT_HOME/conf/web.xml. The section of web.xml that contains a disabled readonly parameter follows.

Exploiting the Vulnerability

We tested the exploitation of CVE-2025-24813 in March 2025. Exploiting this vulnerability consists of two steps:

  • First, stage the payload by ending it as a file through an HTTP PUT request with content range and a self-defined filename in the URL. This file contains serialized malicious code for later deserialization.
  • Next, trigger the exploit by sending an additional HTTP GET request containing a cookie consisting of JSESSIONID= immediately followed by the self-defined filename prefixed by a period. In this case, the cookie line would read Cookie: “JSESSIONID=.[filename] as Figure 1 below shows. This will trigger deserialization of the cache to run the malicious code.
Figure 1. Two steps of the exploit.

Step 1: Stage the Serialized Malicious Code

This first step consists of sending a file of serialized malicious code as the body of an HTTP PUT request. Apache Tomcat will cache the malicious code as a session file on the local file system, since the name of the file in the URI ends in .session as Figure 2 shows in the PUT header line.

Figure 2 shows the first step’s PUT request with gopan.session as a filename. The format of this HTTP PUT request from the traffic is: PUT /[filename].session HTTP/1.1

A screenshot of an HTTP PUT request with part of its header and file content shown. The header includes information about the host, connection type, and content length. A highlighted section indicates the file name "gopan.session" is sent as the content body of the request.
Figure 2. Payload in step 1.

Step 2: Trigger the Exploit

The second step consists of sending a follow-up HTTP GET request to trigger the exploit and run the malicious code. Figure 3 shows the HTTP GET request with the JSESSIONID cookie value used in the previous step. The format of this cookie is: Cookie: JSESSIONID=.[filename]

Screenshot of a computer terminal displaying HTTP requests and responses. The response shows an HTTP 500 error, and some of the cookie data refers to file names 'gopan' and 'gopan-family'.
Figure 3. Exploiting the vulnerability to run the payload previously sent in step 1.

The cookie value for this exploit uses a period (.) before the filename value of the JSESSIONID. This leading period will lead Tomcat to save the session file with the leading dot.

Source Code Analysis

How Tomcat Caches the PUT Body to a File

As Figure 4 shows, Tomcat first checks if the readonly flag is enabled in the configuration file. If so, Tomcat does not write any code to the cache, including the malicious code.

Flowchart detailing interactions between HttpServlet operations. It starts with 'doPut' handling a request and response, checking feasibility and range before deciding to execute 'executePartialPut' or 'write req, save the file'. Another branch shows 'replacePartialPut' handling a string request, creating a temporary file, and verifying the file object as well as writing the session to the file object.
Figure 4. Step one: From PUT to write a file.
  • If the readonly flag is not enabled, Tomcat will also check the Content‑Range field in the HTTP header
  • If the request lacks a Content‑Range header, Tomcat ends the process
  • If the request has a Content‑Range header, Tomcat saves the session data from the HTTP PUT request, in this case gopan.session, in two locations as shown in Figure 5
    • The first is saved as a normal cache file under $TOMCAT_HOME/webapps/ROOT/ without the leading period
    • The second is saved as a temporary file with a leading period under the work directory at $TOMCAT_HOME/work/Catalina/localhost/ROOT/
Screenshot of a directory structure in an IDE, highlighting the Apache Tomcat installation with files under the work directory. Root directory of Tomcat installation. Session file without leading period in file name stored as normal file under the current cache directory. Session file with leading period in file name stored as a temporary file under the work directory.
Figure 5. Cached session file.

Crucially, when Tomcat restores a session, it also loads the cached session file from the same work folder.

Figures 6 and 7 show code segments from the default Java servlet that Tomcat uses to load cached session files when restoring a session at java/org/apache/catalina/servlets/DefaultServlet.java. Comments in yellow describe actions taken by the code.

Screenshot of a Java program displaying code related to handling HTTP server requests and responses.
Figure 6. First code segment from Apache’s default Java servlet used by Tomcat.
Screenshot showing a section of programming code, displayed in a text editor with syntax highlighting.
Figure 7. Second code segment from Apache’s default Java servlet used by Tomcat.
How the Vulnerability Is Triggered by an HTTP Request

When Tomcat receives an HTTP request with a session ID, if session persistence is enabled in the configuration, it will try to find the session in memory. If Tomcat cannot find the session in memory, it restores the session from the saved cache file. At that point, Tomcat deserializes the session file, as shown in Figure 8.

Flowchart representing session management processes. It includes functions like findSession, swapIn, loadSessionFromStore, and load with details on steps like checking if session is in memory, loading from store, and deserializing content.
Figure 8. Step two: From sessionID to deserialization.

Figure 8 illustrates Tomcat’s session management flow. The code that locates sessions, loads them from disk and deserializes their contents is implemented in the following files:

  • java/org/apache/catalina/session/PersistentManagerBase.java
  • java/org/apache/catalina/Store.java
  • java/org/apache/catalina/session/FileStore.java

Figure 9 shows a code segment from java/org/apache/catalina/session/PersistentManagerBase.java that directs Tomcat to find a file for the session data, if the session data is not available in memory.

Screenshot of a computer code in Java. The code includes a method called findSession with comments explaining parts of the code logic related to checking session availability in memory and retrieving it from a file if not found.
Figure 9. Code segment from PersistentManagerBase.java to find session data as a file if not in memory.

Figures 10 and 11 show code segments from the same PersistentManagerBase.java file that illustrate how it loads the session data from a saved cache file.

Screenshot of computer code featuring syntax for session management and exception handling.
Figure 10. Code segment from PersistentManagerBase.java to load session from file (1 of 2).
Screenshot of a code snippet displaying a method named 'loadSessionFromStore'. The code includes exception handling and logging error messages.
Figure 11. Code segment from PersistentManagerBase.java to load session from file (2 of 2).

As Figure 11 shows, store.load(id) triggers deserialization, awakening the malicious code previously embedded in the file by the attacker. This results in arbitrary code execution.

Reviewing this source code first reveals how Tomcat saves session data from an HTTP PUT request, a process by which an attacker can store malicious code. This review also provides insight on how an exploit for the CVE-2025-24813 vulnerability can be triggered by a single follow-up HTTP GET request.

But Tomcat is not the only Apache software that we’ve seen exploit attempts for in the wild. We have also noted exploit attempts for two vulnerabilities in Apache Camel.

CVE-2025-27636 and CVE-2025-29891: Apache Camel

Apache Camel Overview

Apache Camel is an open-source integration framework that allows developers to connect different systems in a reliable and scalable manner. Using Camel, developers can define routing and mediation rules in a variety of domain-specific languages to integrate diverse systems and applications. Apache Camel supports a wide range of protocols and technologies.

Most Camel message handlers are provided as Java packages, allowing the developer to select which packages to include in their product.

Exploitation Details

Whether encrypted or unencrypted, HTTP is a common method for sending data across the internet. While Camel uses various types of HTTP components like Jetty and Netty, Camel ultimately routes the parsed HTTP messages back to its core components, known as camel-core, for further processing.

To facilitate data exchange between Camel and its HTTP components like Jetty and Netty, developers devised a method using key-value pairs to store important contextual information, such as the HTTP response code. Since the HTTP headers are used in processing, Camel also stores the HTTP headers within the same key-value pair. To avoid conflicts between internal contextual information and external data, Camel developers added a Camel prefix to all internal context keys and implemented a filter to prevent the external headers from causing issues (Figure 12).

Diagram showing two sections labeled HTTP Headers and Camel Headers, each containing examples of specific header names like User-Agent, Host, Accept, CamelExecCommandExecutable, and CamelHttpResponseCode.
Figure 12. Normal HTTP headers compared to Apache Camel HTTP headers.

However, since the filter operates on a case-sensitive basis, an attacker could potentially bypass it by altering the case of the headers.

Source Code Analysis

By default, Camel registers the default header filter handler. It asks the filter to ignore all header lines that start with Camel, camel and org.apache.camel. The code for this is at components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java, and Figure 13 shows the applicable segment.

Image of a code snippet named HttpHeaderFilterStrategy, showing methods related to filtering HTTP headers. Includes code comments and elements like filter conditions specifying camel case and domain names.
Figure 13. Code segment from HttpHeaderFilterStrategy.java to ignore specific header lines.

Camel enumerates HTTP request headers, runs the applyFilterToExternalHeaders function and writes the headers to an internal map using components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java as Figure 14 below shows.

Screenshot of a computer code snippet that includes code for reading HTTP headers in a servlet request, with comments and conditional statements.
Figure 14. Code segment from DefaultHttpBinding.java.

The header filtering logic does different matches based on Camel’s configuration. By default, Camel only uses tryHeaderMatch to only check for the beginning of the header. This is done through core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java as Figure 15 below shows.

Screenshot of code for handling HTTP header filters. Underlined in red and indicated by a red arrow is tryHeaderMatch.
Figure 15. Code segment from DefaultHeaderFilterStrategy.java showing tryHeaderMatch.

Assuming an attacker overrides the header CAmelExecCommandExecutable using a capital A in the word CAmel, and the developer is using the camel-exec package, camel-exec will read the value and execute it through components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java, as Figure 16 below shows.

Screenshot of code from the Apache Camel project featuring the DefaultExecBinding class, which includes method implementations and parameter handling related to command execution.
Figure 16. Code segment from DefaultExecBinding.java.

If a developer has set this endpoint to execute a benign executable, the attacker can replace the endpoint with a dangerous command, using a reverse shell. The attacker can potentially get a reverse shell through the remote command execution.

Telemetry

During March 2025, our telemetry had identified 125,856 scans, probes or exploit attempts originating from more than 70 countries for Tomcat vulnerability CVE-2025-24813 and Camel vulnerabilities CVE-2025-27636 and CVE-2025-29891. As our analysis of the trigger data in Figure 17 shows, the frequency of this activity surged immediately after these exploits were announced in mid-March 2025, reaching its peak within the first week.

The data further indicates the presence of both automated scanners and active exploits in the wild.

Line graph depicting the number of triggers over time. The graph shows dates on the x-axis from 2025-03-16 to 2025-03-30, with trigger numbers increasing initially, peaking mid-period, and then decreasing by the end date. Unit 42 and Palo Alto Networks logo lockup.
Figure 17. Detection of exploit activity in March 2025.

Exploit Attempt Payloads

We captured payloads that attackers have used so far in these scans, probes and exploit attempts.

Figure 18 shows an example of the initial HTTP PUT request for an exploit attempt of Apache Tomcat vulnerability CVE-2025-24813. This type of activity is a scan or probe to determine if a server is running a vulnerable version of Tomcat.

A screenshot of an HTTP PUT request showing headers and partial Java code related to HashMap and URL classes. Some information is redacted for privacy.
Figure 18. HTTP PUT request for exploit of CVE-2025-24813.

If successful, the exploit in Figure 20 results in the victim server attempting to contact an out-of-band application security testing (OAST) server.

Figure 19 shows the HTTP request for an exploit of Apache Camel vulnerability CVE-2025-27636. If successful, this would cause the server to run an echo command. This is a way to test a server running Apache Camel if an attacker already has access and can see the results of an echo command.

Screenshot of an HTTP GET request with visible headers including Host, User-Agent set to curl/7.61.1, and Accept being any type, followed by a command execution attempt. Some information has been redacted.
Figure 19. HTTP request from Apache Camel exploit for CVE-2025-27636.

Figure 20 shows the HTTP request for an exploit of Apache Camel vulnerability CVE-2025-29891. Like the exploit attempt for Apache Tomcat shown in Figure 20, this Apache Camel exploit would ask the vulnerable server to contact an OAST server.

Screenshot showing a GET and POST request example with the URL partially visible as "http://". Some of the information is redacted.
Figure 20. HTTP request from Apache Camel exploit for CVE-2025-29891.

CVE-2025-24813 Exploit in the Wild

Since we released our coverage for this vulnerability, we have observed 7,859 exploit attempts for the Apache Tomcat vulnerability CVE-2025-24813.

In this section, we analyze this activity from two perspectives: the length of the session name and the value of the Content‑Range header.

Tomcat Session Name Length

As noted in our earlier analysis, exploits for CVE-2025-24813 use a name appended by .session in the initial HTTP request. This .session file contains the code the vulnerable host will run if an exploit is successful.

Most of the prefixes in these session names use fewer than 10 characters. Our telemetry reveals that the most common prefixes use six characters as a session name as Figure 21 shows.

Bar chart displaying the number of characters in session names. The x-axis represents the count of session names, and the y-axis lists ranges of character counts from less than 4 to 10 or more. Unit 42 and Palo Alto Networks logo lockup.
Figure 21. Trends on length of the session name in CVE-2025-24813 exploit attempts.

We noted this pattern length of six characters in more than 6,000 detections. Why would the vast majority of this exploit activity use a session name with a six-character string? This activity pattern correlates with the Content-Range header.

Tomcat Content-Range Header

As noted in our Tomcat source code analysis for CVE-2025-24813, the HTTP header for Content-Range is an important factor in this vulnerability. Figure 22 groups the different Content-Range values.

A horizontal bar chart showing counts of different byte ranges, with a varying count for each category. Unit 42 and Palo Alto Networks logo lockup.
Figure 22. Trends on Content-Range values seen in CVE-2025-24813 exploit attempts.

Our telemetry reveals we noted the header Content-Range: bytes 0-452/457 in more than 6,000 detections. This finding correlates with the six-character session name.

These two findings match the pattern of a CVE-2025-24813 template for the Nuclei Scanner by ProjectDiscovery available on GitHub. Figure 23 highlights the correlation with our findings.

Screenshot of a text editor displaying code with highlighted lines related to an HTTP session and Python variables. Three sections are emphasized in red boxes. These are the filename, PUT and Content-range.
Figure 23. Segment from the CVE-2025-24813 template in the nuclei-templates GitHub repository.

This means that a large number of the CVE-2025-24813 scans we’ve seen so far have used the Nuclei Scanner. This makes sense, since Nuclei is a freely available scanner under the MIT license that anyone can use. Both attackers and defenders would likely use this scanner and template to check for the vulnerability.

Conclusion

Vulnerable Apache Tomcat instances that allow write directory (disabled by default) and partial PUT (enabled by default) are vulnerable to CVE-2025-24813. Vulnerable Apache Camel instances that use specific components are vulnerable to CVE-2025-27636 and CVE-2025-29891.

These vulnerabilities present a significant security risk due to their critical flaws. Attackers can exploit them through specifically crafted HTTP requests.

Such exploits not only enable potential remote code execution, but they also pose broader threats such as data breaches and lateral movement within the network. The use of Nuclei Scanner to check for this vulnerability underscores the ease with which less-skilled adversaries can leverage these vulnerabilities, making immediate action crucial.

Palo Alto Networks Protection and Mitigation

Palo Alto Networks customers are better protected from the threats discussed above through the following products:

If you think you may have been compromised or have an urgent matter, get in touch with the Unit 42 Incident Response team or call:

  • North America: Toll Free: +1 (866) 486-4842 (866.4.UNIT42)
  • UK: +44.20.3743.3660
  • Europe and Middle East: +31.20.299.3130
  • Asia: +65.6983.8730
  • Japan: +81.50.1790.0200
  • Australia: +61.2.4062.7950
  • India: 00080005045107

Palo Alto Networks has shared these findings with our fellow Cyber Threat Alliance (CTA) members. CTA members use this intelligence to rapidly deploy protections to their customers and to systematically disrupt malicious cyber actors. Learn more about the Cyber Threat Alliance.

Indicators of Compromise

CVE-2025-24813

Source IP addresses seen for CVE-2025-24813

  • 54.193.62[.]84
  • 96.113.95[.]10
  • 209.189.232[.]134
  • 162.241.149[.]101
  • 167.172.67[.]75
  • 100.65.135[.]245
  • 138.197.82[.]147
  • 123.16.159[.]102
  • 193.53.40[.]18
  • 91.208.206[.]203
  • 212.56.34[.]85
  • 195.164.49[.]70
  • 185.91.127[.]9

Activity URLs – CVE-2025-24813

  • PUT /qdigu/session
  • PUT /UlOLJo.session

SHA256 Hash of Payload Samples

  • 6a9a0a3f0763a359737da801a48c7a0a7a75d6fa810418216628891893773540
  • 6b7912e550c66688c65f8cf8651b638defc4dbeabae5f0f6a23fb20d98333f6b

CVE-2025-27636, CVE-2025-29891

Source IP Addresses Seen for CVE-2025-27636, CVE-2025-29891

  • 30.153.178[.]49
  • 54.147.173[.]17
  • 54.120.8[.]214
  • 139.87.112[.]169
  • 139.87.112[.]115
  • 64.39.98[.]52
  • 139.87.112[.]98
  • 139.87.113[.]24
  • 64.39.98[.]139
  • 54.96.66[.]57
  • 138.197.82[.]147
  • 22.85.196[.]34
  • 64.39.98[.]245
  • 64.39.98[.]9
  • 54.120.8[.]207
  • 130.212.99[.]156
  • 139.87.112[.]121
  • 139.87.113[.]26

Activity Headers for CVE-2025-27636, CVE-2025-29891

  • CAmelHttpResponseCode
  • CAmelExecCommandExecutable
  • CAmelExecCommandArgs
  • CAmelBeanMethodName

Additional Resources

 

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email

Comments are closed.