We recently published a blog post exploring a documented limitation of the Google Cloud Armor WAF related to the maximum size of HTTP POST request bodies that can be inspected and blocked by the service. Cloud Armor only inspects the first 8192 bytes (8 KB) of incoming HTTP POST request bodies.
The default behaviour for Cloud Armor when a request exceeds the 8 KB limitation - specifically, when a payload that would otherwise be blocked is included after the first 8192 bytes of an HTTP POST request body - is to let the request pass directly to the underlying web application. This may result in weaknesses in the underlying web application to be exposed to attackers and can lead to compromise of the underlying web application.
How can this be mitigated?
A Cloud Armor rule to filter and block requests where the value of the Content-Length HTTP request header exceeds 8192 bytes can be used to mitigate the impact of the bypass.
int(request.headers["content-length"]) >= 8192
The rule can be configured to respond with a 502, 403, or 404 HTTP response status.
This rule by itself, however, may not be suitable for certain applications or situations. For instance, content-heavy applications (such as logging or CMS software) may suffer from fallout as a result of such a rule being in place, considering that a number of legitimate requests may be expected to be large in size.
In such cases, further conditions could be added along with the Content-Length check to finely tune when Cloud Armor filters and blocks requests. For instance, a rule that would allow requests larger than 8 KB only for a specific endpoint could be added to the security policy targeting a given application.
A condition to check the “request.path.matches” attribute can be used for such a rule. Cloud Armor’s custom rules language has several other attributes that can be useful for filtering requests in such scenarios.
request.path.matches('/safe_path/') && int(request.headers["content-length"]) >= 8192
Special attention should be given to the Priority value of rules to avoid conditions where requests erroneously end up passing through Cloud Armor to an underlying application. Rule priority ranges from 0 (highest priority) to 2,147,483,647 (lowest).
While this limitation is highlighted in the documentation for Cloud Armor, the impact it could have may still not be known widely enough.
To mitigate the risk of attacks that use the 8 KB bypass to circumvent Cloud Armor and reach an underlying application, a custom Cloud Armor rule for checking the value of “Content-Length” header can be created. Additionally, follow the principle of defence in depth, applications should be tested for bugs frequently, dependencies should be kept up-to-date, and secure coding practices should be followed even when an application is protected by a web application firewall.