Proof of Concept for "Apache Httpd Limited cross-site scripting in mod_proxy error page (CVE-2019-10092)"

A few days ago, I came across the Apache Httpd Security Page and read about a XSS issue in mod_proxy. I couldn't find a Proof-of-Concept right away, so I dug into it and finally managed to exploit it.

Citing the security report for CVE-2019-10092:

low: Limited cross-site scripting in mod_proxy error page (CVE-2019-10092)
A limited cross-site scripting issue was reported affecting the mod_proxy error page. An attacker could cause the link on the error page to be malfomed and instead point to a page of their choice. This would only be exploitable where a server was set up with proxying enabled but was misconfigured in such a way that the Proxy Error page was displayed.
We have taken this opportunity to also remove request data from many other in-built error messages. Note however this issue did not affect them directly and their output was already escaped to prevent cross-site scripting attacks.
Acknowledgements: This issue was reported by Matei "Mal" Badanoiu

Reading through the comments in the bugtracker, I found the changeset that was supposed to fix the issue in the svn repo: r1864191. In the file proxy/proxy_util.c there is:

-            "The proxy server could not handle the request <em><a href=\"",
-            uri, "\">", ap_escape_html(r->pool, r->method), "&nbsp;", uri,
-            "</a></em>.<p>\n"
+            "The proxy server could not handle the request<p>"
             "Reason: <strong>", ap_escape_html(r->pool, message),

The function ap_escape_html maps to ap_escape_html2 and can be found in the github repo in server/util.c. It replaces instances of <, > and " with their html entity equivalents, so it's not possible to break out of the <a href="[url]">...</a> tag directly.

I thought about exploiting it using different protocols a la javascript:alert(1), but any URL will start with a leading /, so this did not work as you can see below:


A while later I came across a tweet with an interesting approach. The trick is to use a vertical tab (%09) and then place another URL in the tag. So once a victim clicks the link on the error page, she will go somewhere else.


As you can see, the browser changes the destination from relative / to an absolute url The exploit is http://domain.tld/%09//otherdomain.tld

Here's the httpd configuration to reproduce the behavior:

    <Location />
        ProxyPass connectiontimeout=1 timeout=2
        Order allow,deny
        Allow from all

Simply open a non-responsive listening socket on port 9000 to emulate a broken proxy (e.g. nc -l -v -p 9000).

UPDATE: There are different configuration issues that will trigger a "ProxyError" in Apache. Here's a small (unexhaustive) list:

A Gateway Error [0] should also work and is only the matter of having KeepAlive On or not. So the module does not necessarily need to wait 300s for a timeout. Here's another one [1]. Configuring frontend/backend SSL wrong might also be an issue [2,3]. Or even application level errors [4]


Hope this helps :-)