How to Prevent Clickjacking Attacks on Forms
Clickjacking, also known as a user interface (UI) redress attack, occurs when a malicious website tricks a user into clicking actionable elements on a hidden, transparent, or disguised webpage embedded within an iframe. When targeted at sensitive forms—such as payment gateways, credential changes, or permission updates—clickjacking can cause unauthorized transactions or account takeovers. Protecting sensitive forms requires a multi-layered defensive strategy combining modern HTTP headers, secure cookie configurations, and defensive UI architecture.
Implement
Content Security Policy (CSP) with frame-ancestors
The most robust and standard defense against clickjacking is the
frame-ancestors directive within the HTTP
Content-Security-Policy header. This directive specifies
which sources are permitted to embed the webpage inside
<frame>, <iframe>,
<object>, <embed>, or
<applet> tags.
Block all framing entirely: For pages containing critical forms (e.g., login, password reset, or payment processing), disallow all framing.
Content-Security-Policy: frame-ancestors 'none';Allow only same-origin framing: If the form must be framed within your own application:
Content-Security-Policy: frame-ancestors 'self';Allow specific trusted domains: If a trusted partner domain needs to host the form:
Content-Security-Policy: frame-ancestors 'self' https://trustedpartner.com;
Set the
X-Frame-Options Header as a Fallback
Before frame-ancestors became the standard, the
X-Frame-Options response header was the primary defense
against UI redressing. While modern browsers prioritize CSP,
X-Frame-Options should still be sent to ensure backward
compatibility with legacy user agents.
Deny framing anywhere:
X-Frame-Options: DENYAllow framing only by the same origin:
X-Frame-Options: SAMEORIGIN
Configure
SameSite Attributes on Session Cookies
Clickjacking relies on the browser automatically sending
authenticated session cookies when an embedded target page is rendered
inside an attacker's iframe. By applying the SameSite
attribute to your session cookies, you prevent cookies from attaching to
cross-site requests.
SameSite=Strict: The cookie is never sent in cross-site requests, entirely preventing authenticated framing from third-party origins.SameSite=Lax: Default in many modern browsers, preventing cookies from being sent in cross-origin frames, which mitigates state-changing actions via clickjacking.
Require Re-Authentication for Critical Actions
Defend sensitive form submissions by requiring real-time verification that cannot be easily spoofed through a single deceptive click:
- Password confirmation: Require the user to re-enter their current password before changing account credentials or transferring funds.
- Multi-Factor Authentication (MFA): Require a one-time passcode (OTP) or hardware token prompt to finalize critical operations.
- CAPTCHA integration: Add a CAPTCHA challenge before submission, making automated or blindly guided click-chains ineffective.
Apply Legacy Frame-Busting Scripts with Caution
Client-side JavaScript frame-busting scripts can attempt to force the framed page to the top window:
if (top !== self) {
top.location = self.location;
}While useful as an extreme fallback for environments where HTTP
headers cannot be altered, frame-busting scripts can often be bypassed
by attackers using HTML5 iframe attributes (e.g.,
sandbox="allow-forms allow-scripts" without
allow-top-navigation). Server-side HTTP response headers
(CSP and X-Frame-Options) must always remain
the primary line of defense.