ThisCalculator

Everyday

Limit Decompression Attacks: Reverse Proxy Setup

Updated · Standard formula, shown below

Limit Decompression Attacks: Reverse Proxy Setup

This guide shows you how to configure reverse proxies and API gateways to defend against decompression-based attacks, such as ZIP bombs and gzip bombs, which can exhaust memory and CPU when a server expands maliciously compressed payloads. You’ll learn to set size limits, disable unnecessary compression, and apply request validation at the edge. No prior security expertise is required, but you should have administrative access to your reverse proxy or gateway and a basic understanding of HTTP headers.

What You’ll Need

  • Access to the configuration file of your reverse proxy (e.g., Nginx, HAProxy, Apache) or API gateway (e.g., Kong, Traefik, Envoy).
  • Knowledge of the service’s restart procedure (e.g., systemctl restart nginx).
  • Optional: a test client like curl to verify behavior.

Step-by-Step

  1. Identify the proxy or gateway component. Determine which layer handles incoming requests. For Nginx, this is the http or server block; for HAProxy, the frontend or backend section; for Apache, the VirtualHost or Directory context.
  2. Disable request body compression if not required. Most proxies do not decompress request bodies by default, but if you have enabled it (e.g., proxy_request_buffering with gzip), turn it off. In Nginx, set proxy_request_buffering off; and avoid using gzip on request data. In HAProxy, do not use compression directives on the request path.
  3. Set a maximum request body size. This limits the compressed payload size. In Nginx, use client_max_body_size 1m; (adjust size as needed). In Apache, use LimitRequestBody 1048576 (bytes). In HAProxy, use maxconn or timeout http-request but for size, use http-request deny if content_length gt 1048576.
  4. Limit decompressed content size. If your proxy can inspect decompressed content (e.g., via a plugin like Nginx’s ngx_http_gunzip_module), set a cap. For Nginx, use gunzip on; and then client_max_body_size applies to the decompressed size, so set it appropriately. For Envoy, use the gzip filter with max_compressed_size and max_uncompressed_size.
  5. Reject requests with unexpected Content-Encoding. Only allow known encodings (e.g., gzip, deflate) and reject others. In Nginx, use if ($http_content_encoding !~* "gzip|deflate") { return 415; } (though Nginx discourages if, this is acceptable in server context). In HAProxy, use http-request deny if hdr(content-encoding) -m not -i gzip deflate.
  6. Enforce a compression ratio limit. Some proxies allow a maximum compression ratio. For example, in Envoy’s gzip filter, set compression_level and max_compressed_size. In Nginx, you can use the ngx_http_gunzip_module but it doesn’t directly limit ratio; instead, you can use a third-party module or rely on the size limits.
  7. Add request timeouts. A decompression bomb can take a long time to process. Set a timeout for receiving the full request body. In Nginx, use client_body_timeout 10s;. In HAProxy, use timeout http-request 10s.
  8. Apply rate limiting. Limit the number of requests per IP to reduce the impact of automated attacks. In Nginx, use limit_req_zone and limit_req. In HAProxy, use stick-table and http-request track-sc0.
  9. Test with a small compressed payload. Use curl --compressed -H "Content-Encoding: gzip" --data-binary @test.gz http://your-proxy/ to verify it passes. Then create a large compressed file (e.g., a 1GB file compressed to 1MB) and confirm it is rejected.
  10. Monitor logs. Check proxy logs for 413 (Request Entity Too Large) or 415 (Unsupported Media Type) responses. Adjust limits based on legitimate traffic.

Common Mistakes

  • Setting limits too low, blocking legitimate large uploads. Always test with real-world payloads.
  • Forgetting to apply limits to both request and response. While the attack is usually on request, responses can also be compressed bombs if the upstream is compromised.
  • Relying solely on the application layer. The proxy is the first line of defense; do not skip these steps because the app has its own limits.
  • Misunderstanding that client_max_body_size applies to the compressed size. In Nginx, if you enable gunzip, it applies to the decompressed size; otherwise it’s the compressed size. Know which one you are setting.
  • Not testing with actual attack payloads. A simple curl test may not simulate a real ZIP bomb.

Tips

  • Use a dedicated reverse proxy like Nginx or Envoy that has built-in security features, rather than a simple forward proxy.
  • Combine limits with a Web Application Firewall (WAF) to detect malicious patterns, but do not rely solely on it.
  • Set limits based on your application’s needs. For a file upload service, you may need a larger limit; for an API that accepts JSON, a small limit is fine.
  • Document your configuration so future administrators understand why limits are in place.
  • Regularly review and update limits as your application evolves.

Troubleshooting

Problem: Legitimate requests are being rejected.
Check the proxy logs for the exact error code. If it’s 413, increase client_max_body_size or LimitRequestBody. If it’s 415, ensure your Content-Encoding regex is not too restrictive.

Problem: The proxy still crashes or runs out of memory.
Your limits may be too high, or the decompression happens before the limit is enforced. Verify that you have disabled request decompression if not needed, and consider using a streaming proxy that can abort mid-decompression.

Problem: The configuration syntax is wrong.
Run a syntax check before reloading. For Nginx, use nginx -t. For HAProxy, use haproxy -c -f /etc/haproxy/haproxy.cfg. For Apache, use apachectl configtest.

Problem: The proxy does not see the Content-Encoding header.
Some clients send the header only when the body is compressed. Ensure your test actually compresses the data using curl --compressed or by setting the header manually.

Frequently Asked Questions

Q: Can a decompression attack happen over HTTPS?
Yes, the attack is independent of encryption. The proxy decompresses after TLS termination, so the same limits apply.

Q: What is a typical safe size limit?
It depends on your use case. For a JSON API, 1MB compressed is generous; for file uploads, you might allow 10MB compressed but limit decompressed to 100MB. Start small and increase as needed.

Q: Does disabling request decompression break legitimate clients?
Only if your clients rely on sending compressed requests. Most clients do not compress request bodies by default, so it’s usually safe to disable.

Q: Should I also limit response decompression?
Yes, if your proxy decompresses responses (e.g., for caching), an upstream could send a bomb. Apply similar limits on the response path.

Q: Can I use a CDN to mitigate this?
Some CDNs have built-in protections, but you should still configure your origin proxy as described.

Q: How do I test if my configuration works?
Create a file that compresses to a small size but decompresses to a huge size (e.g., a 1GB file of zeros compressed with gzip). Send it as a request and verify your proxy rejects it with a 413 or similar.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.