Safeguard
DevSecOps

tomcat-embed-core in Maven: A Security Guide to CVEs and Fixes

The tomcat-embed-core Maven artifact is the embedded Tomcat engine inside most Spring Boot apps, and it has carried several serious CVEs. Here is how to find your version and patch it.

Marcus Chen
DevSecOps Engineer
6 min read

The tomcat-embed-core Maven artifact is the embedded Apache Tomcat servlet engine that runs inside most Spring Boot web applications, and because it processes every HTTP request your app receives, its vulnerabilities are directly reachable and worth patching promptly. Its full coordinates are org.apache.tomcat.embed:tomcat-embed-core, and if you build Spring Boot web apps you almost certainly ship it, usually without ever declaring it yourself. That transitive, invisible nature is exactly why it slips out of date. This guide covers how it gets into your build, the CVEs that have mattered recently, and how to find and fix your version.

What it is and how it reaches your build

Tomcat can run as a standalone server or be embedded directly inside a Java application. Spring Boot uses the embedded route: when you add spring-boot-starter-web, it pulls in spring-boot-starter-tomcat, which pulls in tomcat-embed-core under the org.apache.tomcat.embed group. You get a self-contained JAR that serves HTTP without a separate Tomcat install.

The consequence is that most teams never wrote tomcat-embed-core in their pom.xml. Its version is dictated by the Spring Boot version you chose, sitting two levels down in the dependency tree. So "we're on the latest Spring Boot" is usually the real lever for "we're on a patched Tomcat," and a project stuck on an old Spring Boot release is silently stuck on an old, potentially vulnerable Tomcat engine.

The CVEs that have mattered

Tomcat is a mature project with a disciplined security process, but it is also a huge attack surface, and several recent advisories against org.apache.tomcat.embed:tomcat-embed-core are worth knowing. All verified against Apache's Tomcat security pages and public advisory databases:

  • CVE-2024-56337 is the one that forced a lot of emergency upgrades. It is a remote code execution issue tied to the Default Servlet: on a case-insensitive file system with the default servlet write-enabled, a race between concurrent read and upload of the same file could bypass Tomcat's case-sensitivity checks and get an uploaded file treated as a JSP, leading to RCE. It notably prompted Spring Boot dependency updates, since the versions Spring Boot shipped pulled in an affected Tomcat.
  • CVE-2024-52317 is a request-and-response mix-up: incorrect recycling of the request and response objects used by HTTP/2 could leak one user's request or response to another under load. For a multi-tenant app, cross-user data exposure is a serious confidentiality failure.
  • CVE-2024-34750 is a denial-of-service issue arising from improper handling of exceptional conditions and uncontrolled resource consumption, allowing an attacker to exhaust resources.

The pattern across these is that they are reachable by design. Tomcat handles your inbound traffic, so a flaw in request processing or the default servlet is exposed the moment your app is on the network. That is different from a vulnerability buried in a rarely-called utility library, and it is why Tomcat CVEs deserve fast attention.

How to find your version

Do not guess. Ask Maven what actually resolved. From the project root:

mvn dependency:tree -Dincludes=org.apache.tomcat.embed:tomcat-embed-core

That prints the exact version and the path that pulled it in, which will almost always trace up through spring-boot-starter-tomcat to your Spring Boot parent version. To see everything under the group:

mvn dependency:tree | grep tomcat

Once you know the version, check it against the Apache Tomcat security pages for the relevant major line (10.1.x and 11.0.x are the current maintained branches; the 8.5.x line reached end of life, so anything still on it should be treated as urgent to migrate).

How to fix it

There are two ways to move to a patched tomcat-embed-core, and the order of preference matters.

Preferred: upgrade Spring Boot. Because the version is dictated by Spring Boot's dependency management, bumping to a newer Spring Boot patch release is the clean fix. It pulls in the patched Tomcat along with coordinated updates to everything else, and it keeps your tree internally consistent. This is what the Spring Boot maintainers do in response to Tomcat CVEs, so following their patch releases is the intended path.

When you cannot upgrade Spring Boot immediately: override the version property. Spring Boot exposes the Tomcat version as a managed property, so you can force a newer patch without changing the Boot version:

<properties>
  <tomcat.version>10.1.34</tomcat.version>
</properties>

Treat the override as a temporary bridge. Pinning a Tomcat version ahead of what your Spring Boot release was tested against can introduce subtle incompatibilities, so plan the full Spring Boot upgrade rather than accumulating overrides.

Catch it automatically

Manually running dependency:tree after every advisory does not scale across a portfolio of services. Wire dependency scanning into CI so a newly disclosed Tomcat CVE fails the build the day it lands, with the fixed version called out. Because tomcat-embed-core is transitive, a scanner that only looks at declared dependencies in your pom.xml will miss it entirely; you need one that resolves the full tree. An SCA tool such as Safeguard flags transitive artifacts like org.apache.tomcat.embed:tomcat-embed-core and maps them to the Spring Boot upgrade that fixes them. If Java dependency management across a large codebase is your concern, our SCA product page covers how transitive resolution is handled.

FAQ

Why is tomcat-embed-core in my project if I never added it?

Spring Boot's spring-boot-starter-web pulls in spring-boot-starter-tomcat, which pulls in tomcat-embed-core transitively. You get the embedded Tomcat engine automatically, and its version is set by your Spring Boot version rather than declared in your own pom.xml.

How do I check which version I have?

Run mvn dependency:tree -Dincludes=org.apache.tomcat.embed:tomcat-embed-core from the project root. It shows the resolved version and the dependency path, which almost always leads back to your Spring Boot parent.

Should I upgrade Spring Boot or override the Tomcat version?

Prefer upgrading Spring Boot, because it delivers the patched Tomcat with coordinated, tested updates to the rest of the tree. Override the tomcat.version property only as a temporary measure when you cannot upgrade Boot right away, and plan the full upgrade afterward.

Are Tomcat CVEs actually exploitable in my app?

Often yes, because Tomcat processes your inbound HTTP traffic directly. Issues like the CVE-2024-56337 default-servlet RCE or the CVE-2024-52317 HTTP/2 request mix-up are reachable once your app is exposed on the network, which is why embedded Tomcat CVEs warrant prompt patching.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.