Preventing cache poisoning via HTTP X-headers

      Last updated August 14, 2020

    Fastly service configurations may be vulnerable to cache poisoning if they do not take into consideration the interaction between HTTP "X-" headers used by backends to select content. This vulnerability can be mitigated using a VCL patch or by modifying backend configurations.

    When cache poisoning can occur

    If one or more of your backends uses the contents of the X-Forwarded-Host, X-Rewrite-URL, or X-Original-URL HTTP request headers to decide which of your users (or which security domain) it sends an HTTP response for, you could be impacted by vulnerability. If your site’s Fastly configuration passes one of these headers to your backend and does not factor the contents of it into the effective edge cache key (for example, explicitly or via the Vary HTTP response header), an attacker could potentially cause the edge to store a response with arbitrary content inserted into a victim’s cache.

    An attacker might be able to poison a Fastly customer URL by sending an HTTP request to a site that causes the affected backend to respond with an attacker-controlled response. The malicious response object would be stored in the site’s cache at a poisoned URL. An attacker could then potentially lure a victim site user into browsing the poisoned URL, where they would be served malicious content.

    How to mitigate cache poisoning

    If your origin uses special values to select content for users or to otherwise select between security domains, consider reconfiguring your origin server and applying any corresponding security updates as suggested in our original security advisory. In addition, strip or normalize the values of X-Forwarded-Host, X-Rewrite-URL, or X-Original-URL in VCL.

    To do this, set the vulnerable headers to a known-safe value or unset the headers completely. For example, the X-Forwarded-Host header can be set to the value of the Host header via the following VCL snippet:

    set req.http.x-forwarded-host = req.http.host;

    The X-Original-URL header can be unset via the following VCL snippet:

    unset req.http.x-original-url;

    And X-Rewrite-URL can be unset via the following VCL snippet:

    unset req.http.x-rewrite-url;

    Alternatively, the values could be included in your cache key or Vary header to prevent caching of content across security domains. See our guide to manipulating the cache key for more information.

    Back to Top