CVE-2018-11759 – Apache mod_jk access control bypass
- Due to discrepancies between the specifications of httpd and Tomcat for path handling, Apache mod_jk Connector 1.2.0 to 1.2.44 access controls to endpoints defined by a JkMount httpd directive can be bypassed.
- Notably, if a read-only JK status manager interface is available, it is possible to disclose the internal routes of AJP services served by mod_jk.
- Furthermore, if a read-write JK status manager interface is available, it is possible to hijack or shutdown all traffic traversing mod_jk by altering the configuration of AJP workers, or to conduct internal port scanning.
During a penetration test for one of our customers involving a load balancer/reverse-proxy based on Apache mod_jk serving JBoss/Tomcat webservers, we found out about vulnerability CVE-2018-1323 (reported by Alphan YAVAS from Biznet Bilisim A.S.) affecting mod_jk up to version 1.2.42.
After analyzing the mod_jk 1.2.43 patch to understand this vulnerability, we realized it was a path traversal based on discrepancies between how Apache httpd and Tomcat or other Java servers handled the semicolon character for path resoluton.
Apache httpd interprets semicolons in URL as ordinary characters for path resolution, while Tomcat interprets them as query delimiters (with a similar functionality as “?”). Thus, an attacker could fetch a path such as
http://server/java_app/..; did not trigger a path traversal for the logic of httpd, it was forwarded as is to the Tomcat webserver, which interpreted the string as
This allowed to fetch resources that were not supposed to be accessible on the Tomcat webserver.
Patch-diffing of CVE-2018-1323
We have identified that the vulnerability was not fully understood, as the mod_jk patch did fix this specific path traversal attack against mod_jk, but not the core issue revolving around the handling of semicolons by mod_jk.
Playing with the JK status manager
The JK status manager is an administration interface for mod_jk. When set in read-write, it allows the configuration of AJP workers to connect to Java Web servers to proxy HTTP requests to them.
It is normally possible to restrict access to the JK status manager, for example by using httpd directives such as :
Require ip 127.0.0.1
This directive is supposed to prevent any external access to the JK status manager.
JK status manager access is restricted by the httpd directive
We found out that by injecting a semicolon behind the /jkstatus URL, it was possible to bypass such a restriction.
JK status manager access control bypass (semicolon injection)
It is possible to submit GET parameters after this URL, so that state-changing requests can be made to the JK manager.
GET parameters are interpreted after the semicolon
The impact of acccess bypass on the JK manager could be a denial of service of all applications served by mod_jk, by changing ports used by workers if the JK status manager is set with read-write access, and possibly the hijacking of all web applications served by mod_jk if an attacker connects the corresponding AJP workers to a server in his control.
It would also be theoretically possible to conduct internal TCP port scanning, by changing the destination and port of an AJP worker to an internal host and port, because of the discrepancy of error messages returned by the manager depending on whether the submitted AJP port is valid or not (Bad Gateway versus Service Unavailable). The full impact of this type of SSRF is unknown.
Edition of an AJP worker : An arbitrary hostname and port can be submitted
The JK manager (in read-only) also discloses the hostnames, IPs and ports of internal servers, routes that are served by mod_jk, and the absolute path of the httpd server on the filesystem.
This example of access bypass has a high impact. However, it has to be noted that access control to any endpoint defined through a JkMount directive could possibly be bypassed by a semicolon injection.
A patch is available for mod_jk (version 1.2.46).
Other mitigations include the use of Location values such as
/jkstatus*, which seems to fix the issue.
A Docker environment is available to test this vulnerability on our GitHub
- 06/09/2018 : First contact with Apache Tomcat security team
- 06/09/2018 : First response from Apache Tomcat security team
- 13/10/2018 : mod_jk v1.2.46 fix is released
- 31/10/2018 : CVE-2018-11759 advisory is issued
- 01/11/2018 : Full disclosure
Raphaël Arrouas (Xel) and Jean Lejeune (Nitrax) from immunIT