Clickjacking attacks occur when an attacker try to trick an user to click on certain
buttons/links of a legit website. This attack can take place with malicious HTML frames well hidden in an attacker website.
For instance, suppose a safe and authentic page of a social network (https://socialnetworkexample.com/makemyprofilpublic) which allows an user to
change the visibility of his profile by clicking on a button. This is a critical feature with high privacy concerns. Users are generally well informed
on the social network of the consequences of this action. An attacker can trick users, without their consent, to do this action with the below
embedded code added on a malicious website:
<html>
<b>Click on the button below to win 5000$</b>
<br>
<iframe src="https://socialnetworkexample.com/makemyprofilpublic" width="200" height="200"></iframe>
</html>
Playing with the size of the iframe it’s sometimes possible to display only the critical parts of a page, in this case the button of the
makemyprofilpublic page.
Ask Yourself Whether
- Critical actions of the application are prone to clickjacking
attacks because a simple click on a link or a button can trigger them.
There is a risk if you answered yes to this question.
Recommended Secure Coding Practices
Implement content security policy frame-ancestors directive which is supported by all modern browsers and will specify the origins of
frame allowed to be loaded by the browser (this directive deprecates X-Frame-Options).
Sensitive Code Example
In Express.js application the code is sensitive if the helmet-csp or helmet middleware is used without the frameAncestors
directive (or if
frameAncestors
is set to 'none'
):
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.contentSecurityPolicy({
directives: {
// other directives
frameAncestors: ["'none'"] // Sensitive: frameAncestors is set to none
}
})
);
Compliant Solution
In Express.js application a standard way to implement CSP frame-ancestors directive is the helmet-csp or helmet middleware:
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.contentSecurityPolicy({
directives: {
// other directives
frameAncestors: ["'example.com'"] // Compliant
}
})
);
See