· via dev.to (home feed)
Over two million Tomcat AJP connectors still listen on port 8009
ZoomEye counts more than 2.1 million reachable services on port 8009, Tomcat's default AJP port — a trusted-proxy protocol that browser-based scans and asset inventories never track, a dev.to analysis finds.

More than 2.1 million services are listening on TCP port 8009, the default port of Apache Tomcat's AJP connector, according to search-engine figures cited in a dev.to analysis. About 1.24 million of them advertise an AJP version 13 banner, and roughly 620,000 answer plain HTTP on the same port — behaviour a correctly configured, proxy-fronted connector should not show.
What the AJP connector is for
AJP is a binary protocol that lets a front-end web server such as Apache httpd or IIS hand requests to Tomcat. In the typical deployment, the front end terminates TLS and forwards traffic over AJP so requests do not need to be re-encoded as HTTP. As the dev.to author explains, the protocol can pass attributes — the client's address, the authenticated user, the TLS certificate subject — from the proxy into the servlet container.
That attribute-passing turns into a liability the moment someone other than the proxy can reach the connector: a client talking to the port directly can forge those attributes itself. The canonical example is CVE-2020-1938, widely known as Ghostcat and published in 2020, which NVD documents as allowing crafted AJP requests to make Tomcat treat a caller as already authenticated and, in default configurations, to read files under the web application root. The deeper issue, the dev.to piece argues, is structural: AJP assumes its caller is a trusted reverse proxy, and nothing in the protocol verifies that assumption.
Breaking down the numbers
The analysis rests on four ZoomEye queries run on 2026-10-25:
- 2,107,044 hosts with something listening on 8009 — a raw port count that includes processes that are not Tomcat.
- 1,240,557 services fingerprinted as ajp13, the closest approximation of a reachable AJP connector.
- 620,164 hosts that responded to an HTTP-style request on 8009, which a properly fronted connector should not do. Likely causes include a second service bound alongside the connector, or a management agent that claimed the port after a reconfiguration.
- 64,404 hosts completing a TLS handshake, a small figure because standard designs terminate TLS at the front end and leave the connector in plaintext on a private network.
The author is careful about what these figures mean: they describe reachability at a moment in time, not exploitability. An exposed AJP port is a precondition for the Ghostcat class of attack, not evidence that any given instance is unpatched.
How the exposure happens
Two patterns account for most of it, according to the article. The first is packaging defaults: Docker images, Helm charts and application server profiles frequently publish port 8009 as part of their default port set, creating a listener the operator never chose. The second is legacy consolidation: teams patch the front-end httpd but leave the Tomcat connector reachable from the same subnet — a design that holds only as long as that subnet boundary stays enforced.
Tomcat's own security guidance, the author notes, is straightforward: disable the AJP connector if it is unused, and bind it to loopback if it is. For connectors that must stay up, the recommended checks are that the address attribute restricts the listener to the front-end host, that requiredSecret is set so requests without the shared secret are rejected, and that the front end actually sends that secret — all documented for Tomcat 9 and 10. At the orchestration layer, a container that declares 8009 as exposed is a container whose port may end up published, and that distinction between declared and published tends to escape review.
Why it matters
This is an attack surface that conventional asset inventories miss, because scans enumerating browser-reachable services never see it. Two million reachable instances of a port that exists solely to serve a trusted internal proxy form a very large pool of preconditions for a known and previously exploited vulnerability class. The remediation is cheap — disable, restrict, or require a secret — but only if someone knows the port is there, which is exactly what the ZoomEye counts suggest most operators do not.
- #apache-tomcat
- #ajp
- #security
- #cloud
- #ghostcat