Clickjacking prevention
The Content Security Policy frame-ancestors
directive and the X-Frame-Options
header provide control over how your site may be embedded within an <iframe>
on another site. These features help prevent clickjacking.
Problem
In a clickjacking attack, an attacker tricks a user into interacting with a trusted site in a way that they didn't intend.
Typically, the attacker creates a decoy site which embeds the user's trusted site inside an <iframe>
element. The attacker's site hides the <iframe>
, and aligns some decoy elements so they appear in the same place as elements in the trusted site that perform sensitive actions. When the user tries to interact with the decoy elements, they are inadvertently interacting with the trusted site instead, and may be tricked into performing actions with the trusted site which they did not intend.
See Clickjacking for more details.
Solution
The main solution to clickjacking is to prevent the trusted site from being embedded in an <iframe>
. There are two headers which can be used for this:
Content-Security-Policy: frame-ancestors
is preferred as it provides more granular control over site embedding. It is however not supported in IE11 and earlier, pre-Chromium versions of Edge, Safari 9.1 (desktop), and Safari 9.2 (iOS).X-Frame-Options
is less granular, but it is supported in the older browser set listed above.
The recommendation is to use both unless you know you don't need support for the older browser set.
You should deny all attempts to embed your site unless you really need to. When embedding is required, provide the minimum embedding allowance necessary. Sites that require the ability to be embedded in an <iframe>
must use JavaScript defenses and a robust Content-Security-Policy
to prevent clickjacking from malicious origins. Window.confirm()
can be used as part of your JavaScript defenses to inform the user of the action they are about to perform: See window.confirm()
Protection.
The equivalent options for each setting are as follows:
CSP value | X-Frame-Options value |
Description |
---|---|---|
frame-ancestors 'none' |
DENY |
Deny all embedding attempts. |
frame-ancestors 'self' |
SAMEORIGIN |
Allow only same-origin embedding attempts. |
frame-ancestors https://example.org |
ALLOWFROM https://example.org |
Allow embedding attempts from the specified domain. |
Note:
The X-Frame-Options: ALLOWFROM https://example.org
syntax is deprecated, and most browsers ignore it. You are recommend to set DENY
in such cases instead, and/or rely on the CSP equivalent.
Note:
Setting cookies with the SameSite
directive is also useful in clickjacking cases that rely on the user being authenticated.
Examples
Block the site from being embedded by using X-Frame-Options
and CSP:
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
Allow the site to be embedded only on same-origin pages:
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
Only allow example.org
to embed the site:
Content-Security-Policy: frame-ancestors https://example.org
# Block embedding in browsers that don't support CSP2
X-Frame-Options: DENY
See also
- Clickjacking
- Clickjacking Defense Cheat Sheet on
owasp.org
- Clickjacking Attacks and How to Prevent Them on
auth0.com
(2020)