A Clickjacking attack works by loading a malicious website inside a low-opacity iframe and overlaying it with an innocuous looking button, checkbox or link. This tricks the user into interacting with the vulnerable website beneath. The user is then forced to click the apparently safe UI element, triggering a set of actions on the embedded vulnerable website.
These so called UI Redressing attacks, that take place when the website is loaded within an iframe, are widely discussed in the web security world. We've already discussed the Clickjacking attack and its countermeasures extensively on our HTTP Security Headers Whitepaper.
In this article, we examine research that creatively abuses a Clickjacking attack. Security researcher Raushan Raj found a new attack vector we're calling 'Sound Hijacking in Google Docs'. He realised that the lack of an X-Frame-Options header on docs.google.com could open the door for hackers to take over users’ audio input devices.
The Methodology of the Sound Hijacking Attack
Google enabled Chrome users to use their voice to 'write' into documents and sheets (Tools>Voice Typing).
In his proof of concept, Raj first created an empty Google Docs file and configured the Share settings to 'On - Public on the web'. He then loaded the document in an iframe on his website:
<iframe src=“https://docs.google.com/document/d/XXXXXXX/edit” allow=“microphone *”></iframe>
When visitors landed on Raj’s website, the document acted as a spying tool and began transcripting all the incoming voice from the user’s device into Raj's Docs file!
Feature Policy Mechanism
It's important to note that the allow attribute on the iframe command plays a crucial role in this scenario. This Feature Policy mechanism enables developers to control the browser features that receive user data, using commands specific to each website:
- Location information
- Microphone and camera use
- Multimedia controls
- Gyroscope sensors etc
- And, more
For instance, let’s assume that you allowed example.com to have access to your microphone and camera via your browser. But example.com loads another website called another.com in an iframe. Using the commands in the Feature Policy mechanism, example.com will be able to control the rights that another.com will have when it is loaded on example.com.
Raj had previously discovered a Clickjacking vulnerability on Google Play Store. He was awarded a $2337 bug bounty for the Sound Hijacking vulnerability he found.
The Importance of X-Frame-Options Header in Preventing Clickjacking Attacks
As illustrated, the lack of X-Frame-Options (XFO) header is used to exploit unique attack vectors.
Here are a few notes on the X-Frame-Options header:
- It should be present in the HTTP response of every page
- The frame-ancestors directive of the Content Security Policy (CSP) header can be used instead of X-Frame-Options
Here are some examples of how to set Content Security Policy header with the frame-ancestors directive:
Content-Security-Policy: frame-ancestors 'none'; // Doesn’t load any URLs within an iframe.
Content-Security-Policy: frame-ancestors 'self'; // Has the same use as the SAMEORIGIN parameter.
The advantage of CSP over XFO is that while you can whitelist only one URL with XFO, you can whitelist multiple domains using CSP frame-ancestors. We recommend that you set one of these headers depending on the functions of your website.
Which Browsers Support the X-Frame-Options HTTP Header?
Like many security features, the X-Frame-Options header was not always available in browsers. Instead, the need for such a header became apparent much later. Not all browsers supported it in their first versions. Thankfully, however, almost all modern browsers support X-Frame-Options, either fully or partially.
This image is free to use and is supplied by Caniuse, under the CC BY 4.0 license.
X-Frame Headers Should be Set Across your Entire Web Application
More often than not, a missing X-Frame-Options header is seen as a minor inconvenience instead of a security bug that needs to be fixed. Whether or not the lack of the header results in a critical vulnerability strongly depends on the web page. In general, you should make sure to set it across your entire web application to prevent attacks like the one described in this article.
For further details on Raushan Raj's research, see Clickjackings in Google worth 14981.7$.