Misconfigured Servers Lead To WAF Bypass
By: Colin Murdoch
Many web applications are now behind web application firewalls (WAF), such as Cloudflare or AkamaiGHost, which help to filter malicious user inputs and can assist in protecting the application from a variety of vulnerabilities including cross-site scripting, SQL injection, cross-site forgery, denial of service, and many others.
From an attacker’s perspective, the WAF can be very disruptive to creating a functional proof-of-concept or exploit. Oftentimes, evidence exists that a web application contains a vulnerability, such as the presence of unescaped special characters. Normally, this may lead to cross-site scripting through the injection of a simple payload such as '<script>alert(1)</script>'
. However, the WAF will analyze this input and deem it malicious, and never forward the request to the web application; instead, a 403 Forbidden response is typically returned and the exploit fails.
While it can be possible to still write an exploit and bypass the WAF filtering capabilities, these are often convoluted or may only succeed with somewhat benign payloads that don’t produce useful results. The ideal scenario for the attacker is to simply have a method for bypassing the WAF entirely.
Under normal browsing scenarios, most server redirects and responses will return the CNAME or alias which connects to the WAF proxy, instead of revealing the server fully qualified domain name (FQDN). However, Cycura noticed while testing various clients that many web servers are not configured properly with their WAF proxy server, and a very simple payload can be used to trick the server into revealing its FQDN. This is fantastic for attackers as it will render the WAF completely useless; browsing to the FQDN completely bypasses the proxy, and therefore no filtering or protection mechanisms are performed.
This technique was found to work on hosts protected by both Cloudflare or AkamaiGHost, indicating that there are currently no mechanisms built in to the WAF to help prevent leaking the FQDN. Below is an example of the payload as well as the server response, redacting out any sensitive client details:
:~$ curl -s -D - -k https://app-[REDACTED].com/login/%2e%2e/login/%2e%2e/login -o /dev/null | grep location
location: https://[REDACTED]-uc.a.run.app/login
In the above example, we target the existing resource ‘https://app-[REDACTED].com/login
‘ and append some additional superfluous '/%2e%2e/login'
statements. It appears that when the WAF proxy forwards this to the host server, the host server recognizes that the URL is not in its canonical form. As a result, the server performs the appropriate canonicalization, shortening the effective ‘/login../login/../login
‘ to ‘/login
‘. It then responds with a 302 Redirect so the user can attempt to browse to the unique endpoint at ‘/login
‘. Unfortunately in the process, it returns the host server FQDN instead of the CNAME or alias.
Note that in some cases, we did not even have to target an existing resource, such as when sending a GET request to an API server. In these scenarios, it was sufficient to simply send any superfluous URL such as ‘/abc/../xyz
‘.
At this point, the bypass is relatively simple. Replace any references of ‘https://app-[REDACTED].com
‘ with ‘https://[REDACTED]-uc.a.run.app
‘ and freely test any exploits which were previously filtered.
For the application developers and system administrators, the appropriate remediation is relatively simple. Review the web server configuration, and ensure that all redirects properly reference the intended CNAME or alias address, rather than the FQDN. This is necessary to ensure your server is fully compatible with the WAF proxy. Note that this does come with some risk, as the server may still be exposed to the public internet. While it would be difficult to specifically identify the host server in a targeted attack, automated scanners may inadvertently identify the exposed server address.
An even better remediation would be to keep the host server inside an internal, non-internet exposed network and allow communication to the WAF proxy either on the edge or in the cloud. This will help reduce the impact of a leaked FQDN as the server will not be publicly accessible.