Clickjacking Protection (X-Frame-Options) Setup for Websites
Clickjacking — attack where attacker embeds your site in transparent iframe overlaying another page. User thinks clicking button of third-party site, but actually interacts with yours. Consequences: unintended money transfers, settings change, action confirmation.
X-Frame-Options Header
Forbid browser from embedding page in iframe:
add_header X-Frame-Options "DENY" always;
# or
add_header X-Frame-Options "SAMEORIGIN" always;
| Value | Behavior |
|---|---|
DENY |
Forbids embedding everywhere |
SAMEORIGIN |
Allows only from same domain |
ALLOW-FROM uri |
Deprecated, not supported by modern browsers |
CSP frame-ancestors — Modern Alternative
X-Frame-Options deprecated, frame-ancestors in CSP offers more flexibility:
add_header Content-Security-Policy "frame-ancestors 'none'" always;
# or
add_header Content-Security-Policy "frame-ancestors 'self' https://trusted-partner.com" always;
frame-ancestors 'none' — equivalent to X-Frame-Options: DENY. For maximum compatibility set both headers.
Apache Setup
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Content-Security-Policy "frame-ancestors 'self'"
Laravel Setup
// app/Http/Middleware/SecurityHeaders.php
public function handle($request, Closure $next)
{
$response = $next($request);
$response->header('X-Frame-Options', 'DENY');
$response->header('Content-Security-Policy', "frame-ancestors 'none'");
return $response;
}
Exceptions for Widgets
If part of site intentionally embedded (payment form, widget, embed player), apply granular setup via CSP on specific routes, not globally.
Implementation Timeline
Header setup — 1–2 hours including testing in all target browsers.







