Storage quota side-channel attacks in the browser

Request and you will conquer

At the Black Hat USA 2016 conference, we presented “HEIST”. In a nutshell, HEIST is a set of techniques that exploit timing side-channels in the browser to determine the exact size of an authenticated cross-origin response. These side-channels allow an adversary to determine whether a response fitted into a single TCP window or whether it needed multiple. Combined with having content of the request reflected into the response, or by leveraging HTTP/2’s parallel requests, an attacker can determine the exact amount of bytes that were needed to send the response back to the client, all from within the browser. It so happens to be that knowing the exact size of a cross-origin resource is just what you need to launch a compression-based attack, which can be used to extract content (e.g. CSRF tokens) from any website using gzip compression. If you are interested in knowing all the details, I gladly invite you to have a look at the whitepaper, slides, or video of the talk.

The week after Black Hat, we went to the USENIX Security conference, to present our paper titled “Request and Conquer: Exposing Cross-Origin Resource Size”. As the title already gives away, in the paper we explore various methods that can be used to expose the size of cross-origin resources. An interesting technique that we discovered as part of our analysis, was to leverage the browser’s storage mechanisms, and more precisely the quota that is applied to it. In this post, I will discuss a small part of the techniques that we discovered (have a look at the paper if you want to know the full details). I will also discuss something that we discovered after the paper was published, namely how these techniques can be used to launch compression-based attacks (similar to HEIST, but even more stable).

››› Continue reading

Timing Attacks in the Modern Web

The Clock is Still Ticking

Before you explore all the details of these browser-based timing attacks, head over to my laboratories to play around with these attacks yourself!

Timing attacks have been known for a long time. One of the earliest, and possibly the most well-known attacks that leverage timing as side-channel information, are those reported by Paul Kocher in 1996 (to give you an idea, that’s around the same time cookies were first introduced to the web). In his paper, Kocher describes that by measuring the execution time of private key operations, it becomes possible to factor RSA keys and break other cryptosystems such as Diffie-Hellman. After all these years, timing attacks are still highly relevant (you may have heard about the Lucky 13 attack).

In the context of the web, one of the earliest mentions of timing attacks was in 2007, by Bortz and Boneh. In their work, the researchers introduced two types of web-based timing attacks: direct timing attacks and cross-site timing attacks. The former describes the scenario where the adversary directly (hence the name) interacts with the web server. For instance, by measuring the time the server takes to process a POST request to the /login endpoint, the attacker can infer the existence of a username. Similarly, when passwords are checked character by character, the adversary can leverage the timing information to figure out at which position the password comparison failed, and use this information to reveal a victim’s password.

Cross-site Timing Attacks

The remainder of this post will focus on the other type of timing attack, namely the cross-site timing attack. The main difference with direct timing attacks is that in this scenario, it is not the attacker that sends out requests to the targeted website. Instead, by using JavaScript, the attacker triggers to send out carefully crafted requests. As part of the timing attack, the adversary measures the time it takes for the client to download the associated resource. It is important to note here that the requests sent out by the victim are authenticated, i.e. they contain the Cookie header. This means that the response that is returned to the victim will be based on the state of that victim with the targeted website.

››› Continue reading

Clubbing Seals

Exploring the Ecosystem of Third-party Security Seals

Is this website secure? Well, it just contains statically generated content and holds no personal information, so most likely it is. But how would you be able to tell whether it actually is secure?

This problem is exactly what security seal providers are trying to tackle. These seal providers offer a service which allows website owners to show their customers that their website is secure, and therefore safe to use. This works as follows:

  1. The security seal provider initiates a vulnerability scan towards the to-be-sealed website.
  2. When the website is found to be without vulnerabilities, the website owner can include a seal on his website, which links to the seal provider, and shows the security of the sealed website is A-ok.
  3. In case some vulnerabilities were found, the seal provider reports these to the webmaster, who has a limited amount of days to fix these before the seal becomes invisible (more on this later).
  4. This process is repeated every day, week, month or quarter, depending on the security seal provider.

Now, does having such a security seal on your website actually mean you can trust what the seal provider is claiming, and that your website is secure, or does it actually introduce new types of vulnerabilities and increase the likelihood of compromise? This is exactly what we wanted to find out in our research.

››› Continue reading

ClickJacking vulnerability leads to information leakage in Google Drive

This blog post reports on a ClickJacking vulnerability in Google Drive, which has not been fixed in more than 5 months. I will discuss how this vulnerability was discovered in a semi-automated fashion, what caused the vulnerability and how Google should/could have fixed it.

In an attempt to live up to Mr. Curtis “50 Cent” Jackson’s life guidance (Get Rich Or Die Tryin’), I wanted to come up with something that automated much of the checks I did when hunting bugs manually. One of these checks is to verify whether web pages send out the correct security headers. A header that should be on every web page containing a form which initiates a state-change, is X-Frame-Options. By sending out this header on a web page, a website operator can protect his users against ClickJacking vulnerabilities.

NOTE: X-Frame-Options is not the only mechanism to protect against ClickJacking, the frame-ancestors directive of CSP does this as well.

››› Continue reading

Remote Code Execution exploit in WordPress 3.5.1

Some time ago, I published a blog post describing a PHP Object Injection vulnerability I found in WordPress. At that time, I consciously did not include instructions of how this vulnerability could be exploited. Now, almost three months after the public disclosure of the vulnerability, website administrators have had a reasonable amount of time to update their WordPress installations in order to be secure. Hence, I feel that disclosing an example exploit is acceptable, and will hopefully raise awareness with website administrators that updating (vulnerable) web frameworks is crucial.


The vulnerability I found in WordPress allowed user-generated content to be passed to PHP’s unserialize() function. This allows an attacker to initialize objects of his choosing, given that the file containing the class definition for the object is included at the time the unserialize() function is called. Furthermore, the attacker can also control the values for the attributes of the initialized object. Except for the initialization of an arbitrary object, an attacker is left with his creativity to make the initialized object do something “special”. This is possible because of PHP’s magic methods. For instance, when an object is unserialized, the object’s __wakeup() magic method is called. Later, when the object has fulfilled its duties and gets destructed, the __destruct() method is called.

››› Continue reading

WordPress < 3.6.1 PHP Object Injection

Update WordPress to avoid Remote Code Execution attacks

After reading a blog post about a “PHP object injection” vulnerability in Joomla, I dug a bit deeper and found Stefan Esser’s slides of the 2010 BlackHat conference, which showed that PHP’s unserialize() function can give rise to vulnerabilities when supplied user-generated content.

So basically, the unserialize() function takes a string that represents a serialized value, and unserializes (hence the name) it to a PHP value. This value can be any type, except the resource type (i.e. integer, double, string, array, boolean, object, NULL). When the function is given a user-generated string, this may result in memory leak vulnerabilities in some (older) PHP versions. However, this will not be the focus of this blog post. If you want to learn more about this, you can refer to the aforementioned BlackHat slides.

››› Continue reading

HTML injection in mails sent from Google Scholar

As you might know, Google is running a vulnerability reward program, where they award researchers monetary awards or a place in their Hall of Fame when they responsibly disclose vulnerabilities. With this in mind, I was scooping around on several Google services, including Google Scholar. As I recently started a PhD at K.U. Leuven, I wanted to change my Google Scholar email address, which was my student’s address before. A few seconds later I received the following email:

Google Scholar Verification email (normal)

››› Continue reading

Implicit type conversion in MySQL

A new approach to bypassing WAFs

In some languages, using arithmetic operators on elements that aren’t numeric, give some weird results. In JavaScript for example, [ ] + { } is an Object, while { } + [ ] appears to be NaN.

If these kind of obscure actions occur in a parser that is counted on to be very reliable, things can go bad real quickly. Let’s look at how MySQL behaves…

Trying to add two integers in MySQL will result in an integer of the sum of the given integers. Simple and straightforward, as you can see below.

mysql> SELECT 1+1;
| 1+1 |
|   2 |
1 row in set (0.00 sec)
››› Continue reading