Workflow

Tomcat Ghostcat AJP (CVE-2020-1938)

Flag Apache Tomcat hosts for CVE-2020-1938 by reading Apache Tomcat/x.y.z from a GET 404 probe. Floors 7.0.100 / 8.5.51 / 9.0.31. No AJP.

100%

Notes on this workflow

CVE-2020-1938 — Apache Tomcat File Read

What this checks: whether an Apache Tomcat host runs a version affected by unauth AJP arbitrary file read leading to RCE. Read-only: it fingerprints Apache Tomcat and reads the version, no exploitation.

3. Detection — reads the Apache Tomcat version from the product's default response and version banner, compares to 7.0.100 / 8.5.51 / 9.0.31 (per branch); 6.0.x and 8.0.x are EOL and never patched. Flags vulnerable on an affected build. No exploitation.

1. Target List — paste your Apache Tomcat URLs here, one per line (e.g. https://host.example.com).

Overview

This workflow finds Apache Tomcat and sorts each host by whether its version falls below the CVE-2020-1938 Ghostcat fixed floors. CVE-2020-1938 is an AJP connector flaw that can allow file read or remote code execution on misconfigured Tomcat. This check never opens AJP port 8009 and never reads a file. Give it hostnames, IP addresses, or URLs you are authorised to test. The workflow GETs /nonexistent-ghostcat-probe-404, fingerprints Tomcat from the default 404 page, parses Apache Tomcat/x.y.z, and compares that number to the per-branch floors in the graph (7.0.100, 8.5.51, 9.0.31, with 6.0 and 8.0 treated as EOL stubs). Every host comes back affected or not, so a fleet advisory becomes an evidenced list for exposure management. There is no AJP handshake and no confirm step.

Run it on a schedule when app servers turn over. A restored container image that still ships an unpatched 8.5 line is the reason the same fingerprint stays useful.

Pipeline

  1. Read the target list. Hosts, URLs, or ranges, one per line, become the scope.
  2. GET /nonexistent-ghostcat-probe-404 on each host and fingerprint Tomcat from the 404 page body that embeds Apache Tomcat/x.y.z.
  3. Parse the version and compare it to the CVE-2020-1938 per-branch floors in the graph.
  4. Collect the per-host rows: product match, version, vulnerable flag, and any fetch error.
  5. Emit the summary counts: hosts checked, product hits, vulnerable, and errors.

Inputs

  • Target scope. Hostnames, IP addresses, CIDR ranges, or URLs, one per line. Full URLs and host:port entries work too, since the workflow normalizes each into a bare host. Point it at scope you are authorised to test.

Outputs

  • results.jsonl. One row per host: URL, whether Tomcat was detected, the version read, the vulnerable flag, and detail text.
  • findings.jsonl. The same per-host verdict shaped for triage, with severity set from the vulnerable flag.
  • summary.json. Counts across the list: targets, product hits, vulnerable, and errors, plus the detection notes from the graph.

Integrations

  • HTTP. Unauthenticated GET of /nonexistent-ghostcat-probe-404 only. No AJP:8009 connect and no file-read probe.

Sample output

The records below are illustrative and do not come from a real run. They show one Tomcat host below a CVE-2020-1938 floor, one at or above its branch floor, and one host that is not the product.

urlis_productproduct_versionvulnerabledetail
https://app.example.comtrue8.5.40truebelow branch floor 8.5.51
https://app.example.orgtrue9.0.31falseat or above fixed release
https://shop.example.netfalsenullfalsenot identified as Apache Tomcat
{"cve": "CVE-2020-1938", "total_targets": 3, "product_detected": 2, "vulnerable": 1, "errors": 0}

FAQ

Which Tomcat versions does this flag?

Builds below the per-branch floors in the graph: 7.0.100, 8.5.51, and 9.0.31. The 6.0 and 8.0 lines are EOL stubs in the same table. A version picks the matching band, then compares to that band's floor. The compare uses the string the 404 page itself served.

Does an affected row mean Ghostcat AJP worked?

No. The check only GETs /nonexistent-ghostcat-probe-404 and reads Apache Tomcat/x.y.z. It does not connect to AJP:8009, does not read a file, and does not confirm RCE.

Is this check safe on production?

Yes. It is a read-only unauthenticated GET that expects a 404. It does not touch the AJP connector.

Does the check need credentials?

No. It fingerprints the public HTTP error page the way an external scanner would.

What is CVE-2020-1938?

Ghostcat, an AJP connector vulnerability in Apache Tomcat that can allow file read or remote code execution. This workflow maps hosts to that CVE by HTTP version exposure only.

Get a personalized demo

See Trickest in Action

A 30-minute walkthrough. We map the platform to your stack and answer pricing and deployment questions for your environment.