CloudFlare protects millions of websites from online threats. One of the oldest and most pervasive attacks launched against websites is the Distributed Denial of Service (DDoS) attack. In a typical DDoS attack, an attacker causes a large number of computers to send data to a server, overwhelming its capacity and preventing legitimate users from accessing it.
In recent years, DDoS techniques have become more diversified: attackers are tricking unsuspecting computers into participating in attacks in new and interesting ways. Last year, we saw what was likely the largest attack in history (>400Gbps) performed using NTP reflection. In this attack, the unsuspecting participants were misconfigured NTP servers worldwide. This year, we’re seeing a disturbing new trend: attackers are using malicious JavaScript to trick unsuspecting web users into participating in DDoS attacks.
The total damage that can be caused by a NTP or DNS reflection attack is limited by the number of vulnerable servers. Over time, this number decreases as networks patch their servers, and the maximum size of the attack is capped at the outbound capacity of all the vulnerable servers. For JavaScript-based DDoS, any computer with a browser can be enrolled in the attack, making the potential attack volume nearly unlimited.
In this blog post, we’ll go over how attackers have been using malicious sites, server hijacking, and man-in-the-middle attacks to launch DDoS attacks. We’ll also describe how to protect your site from being used in these attacks by using HTTPS and an upcoming web technology called Subresource Integrity (SRI).
How JavaScript DDoS Works
Most of the interactivity in modern websites comes from JavaScript. Sites include interactive elements by adding JavaScript directly into HTML, or by loading JavaScript from a remote location via the <script src="">
HTML element. Browsers fetch the code pointed to by src
and run it in the context of the website.
The fundamental concept that fueled the Web 2.0 boom of the mid-2000s was the ability for sites to load content asynchronously from JavaScript. Web pages became more interactive once new content could be loaded without having to follow links or load new pages. While the ability to make HTTP(S) requests from JavaScript can be used to make websites more fun to use, it can also be used to turn the browser into a weapon.
For example, the following (slightly modified) script was found to be sending floods of requests to a victim website:
function imgflood() {
var TARGET = 'victim-website.com'
var URI = '/index.php?'
var pic = new Image()
var rand = Math.floor(Math.random() * 1000)
pic.src = 'http://'+TARGET+URI+rand+'=val'
}
setInterval(imgflood, 10)
This script creates an image tag on the page 100 times per second. That image points to “victim-website.com” with randomized query parameters. Every visitor to a site that contains this script becomes an unwitting participant in a DDoS attack against “victim-website.com”. The messages sent by the browser are valid HTTP requests, making this a Layer 7 attack. Such attacks can be more dangerous than network-based attacks like NTP and DNS reflection. Rather than just “clogging up the pipes” with a lot of data, Layer 7 attacks cause the web server and backend to do work, overloading the website’s resources and causing it to be unresponsive.
If an attacker sets up a site with this JavaScript embedded in the page, site visitors become DDoS participants. The higher-traffic the site, the bigger the DDoS. Since purpose-built attack sites typically don’t have many visitors, the attack volume is typically low. Performing a truly massive DDoS attack with this technique requires some more creativity.
Shared JavaScript Compromise
Many websites are built using a common set of JavaScript libraries. In order to save bandwidth and improve performance, many sites end up using JavaScript libraries hosted by a third party. The most popular JavaScript library on the Web is jQuery, with around 30% of all websites using some version of it as of 2014. Other popular scripts included on many websites include the Facebook SDK, and Google Analytics.
If a website has a script tag that points to a third-party hosted JavaScript file, all visitors to that site will download the JavaScript and execute it. If an attacker is able to compromise a server that is hosting a popular JavaScript file and add DDoS code to it, the visitors of all the sites that reference that script become part of the DDoS.
In September 2014, RiskIQ reported that jQuery.com’s website was compromised, which hosts a very popular JavaScript library that could have easily been replaced with a malicious one. The threat of attackers injecting malicious JavaScript into millions of sites is no longer theoretical.
An Aside: Introducing Subresource Integrity
The problem of third party assets being compromised is an old one. There are no mechanisms in HTTP to allow a website to block a script from running if it has been tampered with. To solve this problem, the W3C has proposed a new feature called Subresource Integrity (SRI). This feature allows a website to tell the browser to only run a script if it matches what the site expects.
Take the following script tag:<script src="https://code.jquery.com/jquery-1.10.2.min.js">
The browser will download the .js
file and run it no matter what the content of the file is. If someone were to compromise the hosting site’s servers and replace the file with a malicious script, the browser would run it without question.
With SRI, you can tell the browser to not run the script if it does not match what you expect. This is done using a cryptographic hash. A cryptographic hash is a way to uniquely identify a piece of data. It’s like a fingerprint: no two files have the same hash. With SRI, you can include a hash of the authentic version of the script using an attribute called “integrity”. After downloading the script, the browser will compute its hash and compare it with the expected hash from the script tag. If they don’t match, then the script has been tampered with and the browser will not use it.
<script src="https://code.jquery.com/jquery-1.10.2.min.js"
integrity="sha256-C6CB9UYIS9UJeqinPHWTHVqh/E1uhG5Twh+Y5qFQmYg="
crossorigin="anonymous">
Adding this tag protects your site visitors from a compromise in the third party JavaScript host. Computing the tag is a simple process that only has to be done once. There’s even a service that can compute the hash for you.
UPDATE: The crossorigin
attribute and Cross-Origin Resource Sharing (CORS) headers are required for scripts with SRI in order to ensure the proper enforcement of the browser same-origin policy and prevent Cross-Site Scripting (XSS) attacks.
This feature is not currently supported by many browsers, but it is under development for Chrome and Firefox.
Server compromises are often detected and fixed quickly, so attackers have turned to other ways to insert malicious JavaScript into websites. The newest way they are doing this is a technique we’ve discussed previously: a man-in-the-middle attack.
Man-in-the-middle
Websites get to your browser from a web server by traversing the networks of the Internet and hopping from machine to machine. Any one of the machines that sits between your browser and the server is able to modify the data in any manner, including changing the content of HTML or JavaScript. If the computer sitting in the middle of a communication does something malicious, like adding bad JavaScript to a webpage, this is called a man-in-the-middle attack.
Modifying websites in transit is common monetization technique for ISPs and WiFi providers. This is how some hotel networks, cellular networks and others inject ads and tracking cookies into websites. Self-respecting businesses typically don’t inject attack code into websites, but as part of the Internet they have the capability of doing so.
If an attacker gains a privileged network position similar to an ISP —like a network interconnect or peering exchange— they can also inject JavaScript into websites that pass through their network. If the injected JavaScript contains a DDoS script, all the visitors to the website become DDoS participants. This can happen to any website or web asset that passes through the rogue network.
To make things worse, if the path to popular JavaScript file happens to go through the attacker’s network, the number of browsers participating in the attack can increase dramatically.
The technique that fully stops this sort of code injection is encryption. With HTTPS, all communication between a browser and a web server is encrypted and authenticated, preventing intermediate parties from modifying it. Making your site HTTPS-only prevents your site from being modified in transit. This not only prevents ISPs and WiFi providers from injecting ads and tracking cookies, but it prevents your site from being used in a JavaScript DDoS.
Conclusion
JavaScript-based DDoS attacks are a growing problem on the Internet. CloudFlare sees, and routinely blocks, these attacks for the millions of websites that use our service, and we learn from every attack we see. JavaScript-based DDoS can be launched at any time, so prevent your site from being part of the problem by going HTTPS-only. CloudFlare provides HTTPS and the ability to go HTTPS-only to all customers including those on the free plan.