CVE-2023-34981 - Information Leak in Apache Tomcat (AJP Proxy Header Regression)

Published: June 2023  
Affected Versions: Apache Tomcat 11..-M5, 10.1.8, 9..74, 8.5.88  
Severity: Moderate (Information Disclosure)  
Component: AJP Connector

Overview

In June 2023, a regression was identified in Apache Tomcat—a popular open-source Java Servlet container—introducing an information leak via the AJP protocol. This security vulnerability, tracked as CVE-2023-34981, results in unintended response header reuse in specific proxy scenarios, affecting thousands of web applications worldwide.

This post will break down what happened, how it can be exploited, and why it matters, using simple, clear language and hands-on code and config examples.

What Is CVE-2023-34981?

The vulnerability comes from a misapplied fix to a previously reported Tomcat bug (bug 66512). In certain Tomcat versions, when a response has no HTTP headers, the server’s AJP connector sometimes fails to send the expected SEND_HEADERS message.

This would not be too serious except for how some AJP proxies (such as Apache HTTPD’s mod_proxy_ajp) behave—they reuse the previous response’s headers if none are provided, accidentally leaking sensitive data from one user to another.

Key Impact

- Cross-request Information Leak: One user could see HTTP headers intended for another, potentially exposing session cookies, authentication details, caching headers, etc.

You use the AJP connector (especially if fronted with Apache HTTPD’s mod_proxy_ajp).

- Your application might return responses without any HTTP headers (like simple 200 OKs with an empty body).

1. AJP SEND_HEADERS Regression

The AJP protocol expects the backend (Tomcat) to send a SEND_HEADERS packet for every response, regardless of headers.

With the regression, if there were no headers, Tomcat would skip sending this packet. The proxy server, still waiting, assumes “let's use what was last set,” resulting in a classic case of state leakage.

Proxy mistakenly reuses previous headers from Request 1.

User B now receives headers meant for User A. That’s an info leak.

Diagram

[User A] --->
  [Proxy] --->
    [Tomcat responds with headers]
  <--- [Proxy saves headers]

[User B] --->
  [Proxy] --->
    [Tomcat responds WITHOUT headers due to bug]
  <--- [Proxy "helpfully" reuses previous headers]
[User B receives secrets!]

Below is a simplified example in which the bug causes header mix-up

// Vulnerable Java Servlet
@WebServlet("/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {

        if(req.getParameter("withHeader") != null) {
            resp.setHeader("X-User", "alice");
            resp.getWriter().write("Hello with header!");
        } else {
            // No headers set on response!
            resp.getWriter().write("Hello without header!");
        }
    }
}

Requests

1. /test?withHeader=1  → Response: X-User: alice header is set.
2. /test               → Response should have no headers.

Through the proxy, /test response may incorrectly include the prior X-User: alice.

Configure Apache HTTPD with mod_proxy_ajp

ProxyPass / ajp://localhost:8009/

3. Make two requests as above; if the second response shows headers from the first, you are vulnerable.

References

- CVE-2023-34981 Apache Tomcat Advisory
- Tomcat Security Page
- Upstream Tomcat Bug Report 66512
- mod_proxy_ajp Documentation

Conclusion

CVE-2023-34981 reminds us that even minor-looking protocol specifics—like always sending headers—can lead to privacy leaks when proxies are involved. If your app runs behind an AJP proxy, patch immediately, and always understand the data-flows between your server and the load balancer!

Stay secure. Don’t trust proxies to always “do the right thing”—make it explicit in your server’s responses.

Feel free to share and ask questions below!

*This post is exclusive and a human-readable, practical breakdown for sysadmins, developers, and security engineers facing the ongoing challenge of patching and monitoring Tomcat-based deployments.*

Timeline

Published on: 06/21/2023 11:15:00 UTC
Last modified on: 07/21/2023 19:20:00 UTC