Safeguard
Vulnerability Analysis

CVE-2020-1938 (Ghostcat): File inclusion via Apache Tomca...

Ghostcat (CVE-2020-1938) let attackers read files—and often achieve RCE—via Tomcat's default, unauthenticated AJP connector. Here's the risk, fix, and KEV context.

Nayan Dey
Security Researcher
7 min read

Apache Tomcat's AJP connector shipped with a design flaw that let an unauthenticated attacker read arbitrary files from a web application's context — including configuration files, source code, and credentials — and, on servers that also permitted file uploads, chain that read primitive into remote code execution. Tracked as CVE-2020-1938 and nicknamed Ghostcat, the bug affected the AJP protocol implementation itself rather than a specific application, which meant every Tomcat deployment using the default configuration was exposed the moment the AJP port was reachable. Given how many Java web stacks embed Tomcat under the hood — standalone deployments, Spring Boot apps with embedded Tomcat, and third-party appliances that bundle it — Ghostcat had a wide blast radius and became one of the more consequential Java ecosystem vulnerabilities of 2020.

What Ghostcat actually does

The Apache JServ Protocol (AJP) is a binary protocol Tomcat uses to communicate with front-end web servers like Apache HTTP Server or IIS via mod_jk or mod_proxy_ajp. It's a "trusted" internal protocol — the assumption baked into its design is that only the front-end proxy talks to it, never the public internet.

The problem: Tomcat enabled the AJP connector by default, bound it to all network interfaces (0.0.0.0), and shipped it with no authentication. Because AJP exposes request attributes that let a caller specify arbitrary file paths within a web application (this is how proxies forward things like javax.servlet.include.request_uri), an attacker who could reach port 8009 directly — with no credentials — could request Tomcat treat any file under WEB-INF/ (or other webapp paths) as an "included" resource and return its contents. That's enough to dump web.xml, application source, and any secrets embedded in configuration.

Read access alone is bad. What made Ghostcat critical is the escalation path: if the target application also allowed file uploads in any form, an attacker could upload a file containing JSP code and then use the AJP file-inclusion primitive to have Tomcat execute it as a JSP page — turning an arbitrary file read into full remote code execution on the server.

Affected versions and components

Ghostcat affects the AJP Connector implementation across all actively maintained Tomcat branches at the time of disclosure:

  • Apache Tomcat 9.x — versions before 9.0.31
  • Apache Tomcat 8.5.x — versions before 8.5.51
  • Apache Tomcat 7.x — versions before 7.0.100
  • Apache Tomcat 6.x — also affected, but 6.x was already end-of-life and received no official patch

Because Tomcat is embedded inside countless downstream products — application servers, Java-based appliances, admin consoles, and frameworks that bundle their own Tomcat runtime — the practical list of "affected components" extends well beyond people who consciously chose to run Tomcat. Any product or container image pinning an unpatched Tomcat version inherited the exposure, which is a recurring theme in supply-chain-driven vulnerabilities like this one.

Severity, exploitability, and known exploitation

CVE-2020-1938 was rated Critical, with a CVSS v3 base score of 9.8, reflecting an unauthenticated, network-exploitable vulnerability with high impact on confidentiality, integrity, and availability — the file-read primitive alone threatens confidentiality, and the upload-to-RCE chain threatens integrity and availability.

Proof-of-concept exploit code for Ghostcat became publicly available shortly after disclosure, and it was subsequently used in real-world attack campaigns. That combination — trivial exploitability, no authentication required, an RCE escalation path, and public tooling — is why CVE-2020-1938 has been included in CISA's Known Exploited Vulnerabilities (KEV) catalog, which specifically tracks vulnerabilities with confirmed evidence of active exploitation. For organizations with federal compliance obligations or that use KEV membership as a prioritization signal, Ghostcat sits squarely in the "patch immediately" tier regardless of any theoretical mitigating factors in a given deployment.

Disclosure timeline

  • Discovery — Researchers at Chaitin Tech identified the AJP file-read/inclusion flaw in Apache Tomcat and privately reported it to the Apache Tomcat security team.
  • Coordinated fix — The Apache Tomcat project prepared patches addressing the flaw across the 7.x, 8.5.x, and 9.x branches, released as Tomcat 7.0.100, 8.5.51, and 9.0.31.
  • Public disclosure — CVE-2020-1938 was published in February 2020 alongside the "Ghostcat" name and technical write-ups, at which point proof-of-concept exploits and scanning activity followed quickly.
  • Ongoing exploitation — Given the ease of exploitation and slow patch adoption across embedded and appliance-based deployments, Ghostcat continued to appear in vulnerability scans and incident reports well after disclosure, which is reflected in its KEV listing.

Remediation

The fix for Ghostcat is well understood and has been stable for years, but the vulnerability still turns up in audits because AJP is frequently forgotten rather than actively used.

  1. Upgrade Tomcat. Move to Apache Tomcat 9.0.31, 8.5.51, or 7.0.100 or later. This is the definitive fix and should be the first action for any internet-facing or internally-facing Tomcat instance.
  2. Disable the AJP connector if you don't use it. Most deployments that serve HTTP/HTTPS directly, or that front Tomcat with a reverse proxy over HTTP(S) rather than AJP, don't need the AJP connector enabled at all. Removing or commenting out the AJP <Connector> block in server.xml eliminates the attack surface entirely.
  3. If you must use AJP, restrict and authenticate it. Bind the connector to localhost or an internal-only interface rather than 0.0.0.0, restrict access with firewall rules so only the trusted front-end proxy can reach port 8009, and set the requiredSecret (or secret in newer Tomcat releases) attribute so AJP requests must present a shared secret before Tomcat honors them.
  4. Audit embedded and third-party Tomcat instances. Because Tomcat ships inside many commercial and open-source products, patching your own deployments isn't sufficient — you need an inventory of every place Tomcat is bundled, including containers, appliances, and vendor software, to confirm none of them are still running a vulnerable AJP configuration.
  5. Verify after remediation. Confirm the AJP port is no longer reachable from untrusted networks (or is fully disabled) and re-scan to ensure no residual instances were missed, particularly in older or forgotten environments.

How Safeguard Helps

Ghostcat is a textbook example of why point-in-time patching isn't enough: the vulnerability persisted in the wild for years after a fix existed, largely because organizations didn't have visibility into every place a vulnerable Tomcat version — or an AJP connector left exposed by default — was actually running.

Safeguard's software supply chain platform is built to close exactly that visibility gap:

  • Continuous SBOM and dependency inventory — Safeguard tracks every Tomcat instance, container image, and embedded runtime across your environment, so you know immediately where CVE-2020-1938-affected versions exist, including in third-party or vendor-bundled software you didn't build yourself.
  • KEV- and EPSS-aware prioritization — rather than treating every CVE as equally urgent, Safeguard surfaces vulnerabilities like Ghostcat that are confirmed in CISA's KEV catalog and carry high real-world exploitation likelihood, so remediation effort goes where actual attacker activity is concentrated.
  • Configuration and exposure context, not just version matching — Safeguard correlates vulnerable component versions with actual network exposure and configuration state, helping teams distinguish between "Tomcat is present but AJP is disabled and firewalled" and "AJP is open on the internet with no secret configured" — the difference that determines real risk.
  • CI/CD and registry gating — new builds or container images that pull in an unpatched Tomcat version are flagged before they reach production, preventing Ghostcat-class regressions from re-entering the environment through a stale base image or vendored dependency.
  • Audit-ready remediation tracking — for teams with SOC 2 or other compliance obligations, Safeguard maintains a record of when a vulnerable component was identified, when it was patched or mitigated, and what evidence supports closure — turning a KEV-listed CVE like Ghostcat into a documented, closed-loop remediation rather than a recurring finding.

CVE-2020-1938 is old enough that patches have existed for years, yet it remains a reliable finding in modern supply chain audits precisely because visibility, not patch availability, is usually the bottleneck. Safeguard is designed to remove that bottleneck — so the next Ghostcat-class vulnerability gets found and fixed before it becomes a KEV entry, not after.

Never miss an update

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