Flag Apache Tomcat hosts for CVE-2017-12617 by reading Apache Tomcat/x.y.z from GET /nonexistent-4041c2b7f. Floors 7.0.82 / 8.0.47 / 8.5.23 / 9.0.1. No PUT.
What this checks: whether an Apache Tomcat host runs a version affected by unauth HTTP PUT JSP upload RCE (readonly=false). 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.82 / 8.0.47 / 8.5.23 / 9.0.1 (per branch). 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-2017-12617 fixed floors. CVE-2017-12617 is remote code execution when a misconfigured HTTP PUT allows uploading a JSP. This check never sends a PUT, never uploads a file, and never writes a JSP. Give it hostnames, IP addresses, or URLs you are authorised to test. The workflow GETs /nonexistent-4041c2b7f, 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. Every host comes back affected or not, so a fleet advisory becomes an evidenced list for exposure management. There is no upload confirm and no RCE claim.
Run it on a schedule when app servers turn over. A restored image that still ships an unpatched 8.5 line with readonly left false is the reason the same fingerprint stays useful.
Pipeline
Read the target list. Hosts, URLs, or ranges, one per line, become the scope.
GET /nonexistent-4041c2b7f on each host and fingerprint Tomcat from the 404 page body that embeds Apache Tomcat/x.y.z.
Parse the version and compare it to the CVE-2017-12617 per-branch floors in the graph.
Collect the per-host rows: product match, version, vulnerable flag, and any fetch error.
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-4041c2b7f only. No HTTP PUT, no JSP upload, and no file write.
Sample output
The records below are illustrative and do not come from a real run. They show one Tomcat host below a CVE-2017-12617 floor, one at or above its branch floor, and one host that is not the product.
Builds below the per-branch floors in the graph: 7.0.82, 8.0.47, 8.5.23, and 9.0.1. 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 a JSP was uploaded?
No. The check only GETs /nonexistent-4041c2b7f and reads Apache Tomcat/x.y.z. It does not send a PUT, does not write a JSP, 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 write to the document root.
Does the check need credentials?
No. It fingerprints the public HTTP error page the way an external scanner would.
What is CVE-2017-12617?
Remote code execution in Apache Tomcat when a misconfigured HTTP PUT allows uploading a JSP. This workflow maps hosts to that CVE by HTTP version exposure only.