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
apr_pstrcat(r->pool, - "The proxy server could not handle the request <em><a href=\"", - uri, "\">", ap_escape_html(r->pool, r->method), " ", uri, - "</a></em>.<p>\n" + "The proxy server could not handle the request<p>" "Reason: <strong>", ap_escape_html(r->pool, message), "</strong></p>", NULL));
ap_escape_html maps to
ap_escape_html2 and can be found in the github repo in server/util.c. It replaces instances of
" 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
/, 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
https://enoflag.de. The exploit is
Here's the httpd configuration to reproduce the behavior:
<Location /> ProxyPass http://127.0.0.1:9000/ connectiontimeout=1 timeout=2 ProxyPassReverse http://127.0.0.1:9000/ Order allow,deny Allow from all </Location>
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  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 . Configuring frontend/backend SSL wrong might also be an issue [2,3]. Or even application level errors 
Hope this helps :-)