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:

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>

" + "The proxy server could not handle the request<p>" "Reason: <strong>", ap_escape_html(r->pool, message), "</strong></p>", NULL));

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 https://enoflag.de . The exploit is http://domain.tld/%09//otherdomain.tld

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 [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]

[0] https://serverfault.com/questions/185894/proxy-error-502-reason-error-reading-from-remote-server-with-apache-2-2-3-de

[1] https://github.com/aio-libs/aiohttp/issues/2687

[2] https://serverfault.com/questions/915002/502-from-apache-over-https-with-reverse-proxy-to-node-server-on-different-port

[3] https://serverfault.com/questions/742850/502-proxy-error-apache-reverse-proxy

[4] https://www.experts-exchange.com/questions/29108337/Apache-proxy-Error-reading-status-line-from-remote-server.html

Hope this helps :-)

-=-