Clickjacking Prevention in WordPress

Clickjacking is a deceptive UI attack where your website is loaded inside a hidden or transparent <iframe>, tricking users into clicking buttons they never meant to. Effective Clickjacking Prevention in WordPress involves sending the correct HTTP security headers, testing them thoroughly, and allowing only the embeds you truly need. In this guide, you’ll get practical, copy-paste code for Apache, Nginx, and WordPress, plus testing steps and troubleshooting tips.

Clickjacking Prevention in WordPress: 10 Proven Tips

Why Clickjacking Prevention in WordPress Matters

Attackers can overlay your site within their page and invisibly funnel clicks to sensitive actions (e.g., “Delete account,” “Change email,” “Submit payment”). If your site allows framing by default, you’re at risk. Clickjacking Prevention in WordPress relies primarily on:

  1. X-Frame-Options (legacy but still widely respected): DENY, SAMEORIGIN, or ALLOW-FROM (discouraged—poor support).
  2. Content-Security-Policy: frame-ancestors …: modern, flexible control over which origins may embed your site.

Best practice: Use CSP frame-ancestors and keep X-Frame-Options as a compatible backup.


Quick Wins for Clickjacking Prevention in WordPress

  • Send both X-Frame-Options: SAMEORIGIN and Content-Security-Policy: frame-ancestors 'self'.
  • If you must allow specific partner domains, allowlist them with frame-ancestors.
  • Test with a minimal attacker page (below) to confirm your headers block framing.
  • Apply these headers to every route, including /wp-admin/ and sensitive front-end forms.

Apache (.htaccess) Configuration

Add to your WordPress site’s .htaccess (in the web root):

# Clickjacking Prevention in WordPress via Apache (.htaccess)
<IfModule mod_headers.c>
  # Legacy header for broad support
  Header always set X-Frame-Options "SAMEORIGIN"

  # Modern, flexible control (adjust allowlist as needed)
  Header always set Content-Security-Policy "frame-ancestors 'self';"
</IfModule>

Allowlisting a Trusted Domain (e.g., your support portal)

<IfModule mod_headers.c>
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Content-Security-Policy "frame-ancestors 'self' https://support.example.com;"
</IfModule>

Note: If you use an iframe-based widget (chat, booking), add its exact origin to frame-ancestors.


Screenshot of our Free Website Vulnerability Scanner homepage

Here, you can view the interface of our free tools webpage, which offers multiple security checks. Visit Pentest Testing’s Free Tools to perform quick security tests.
Here, you can view the interface of our free tools webpage, which offers multiple security checks. Visit Pentest Testing’s Free Tools to perform quick security tests.

Nginx Configuration

In your site’s server block:

# Clickjacking Prevention in WordPress via Nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "frame-ancestors 'self';" always;

Allowlist a partner domain:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "frame-ancestors 'self' https://support.example.com;" always;

Reload Nginx after changes:

sudo nginx -t && sudo systemctl reload nginx

WordPress-Only Approach (No Server Access)

If you can’t touch the web server, enforce Clickjacking Prevention in WordPress via PHP. Use the send_headers hook in functions.php or a small must-use plugin.

functions.php (theme-level)

// Clickjacking Prevention in WordPress via functions.php
add_action('send_headers', function () {
    header("X-Frame-Options: SAMEORIGIN");
    header("Content-Security-Policy: frame-ancestors 'self';");
});

Safer: A Tiny MU-Plugin (survives theme changes)

Create /wp-content/mu-plugins/security-headers.php:

<?php
/**
 * Plugin Name: Security Headers - Clickjacking Protection
 * Description: Adds X-Frame-Options and CSP frame-ancestors for Clickjacking Prevention in WordPress.
 */

add_action('send_headers', function () {
    // Adjust allowlist as required
    header("X-Frame-Options: SAMEORIGIN");
    header("Content-Security-Policy: frame-ancestors 'self';");
});

Allowlist (When You Must Embed on a Known Domain)

add_action('send_headers', function () {
    header("X-Frame-Options: SAMEORIGIN");
    header("Content-Security-Policy: frame-ancestors 'self' https://support.example.com https://partner.cdn.example;");
});

Testing: Prove Your Headers Work

  1. Create a simple attacker page on a separate domain (or local file):
<!-- attacker.html -->
<!doctype html>
<title>Test Clickjacking</title>
<style>iframe { width: 100vw; height: 100vh; opacity: 0.01; }</style>
<iframe src="https://your-site.example/"></iframe>
  1. Open attacker.html in a browser.
    • If framing is blocked, you’ll see nothing or a console error.
    • Check DevTools Network → Response Headers for X-Frame-Options and Content-Security-Policy.
  2. CLI check:
curl -s -I https://your-site.example/ | egrep -i "x-frame-options|content-security-policy"

Sample assessment report by our free tool to check Website Vulnerability

A sample vulnerability report provides detailed insights into various vulnerability issues, which you can use to enhance your application’s security.
A sample vulnerability report provides detailed insights into various vulnerability issues, which you can use to enhance your application’s security.

Granular Control: Only Allow Framing on a Specific Page

Some flows (e.g., checkout embedded in a partner app) may require framing only on one URL.

Apache per-location (WordPress pretty permalinks):

<IfModule mod_headers.c>
  # Default deny framing everywhere
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Content-Security-Policy "frame-ancestors 'self';"

  # Allow framing for a specific path
  <LocationMatch "^/embed/checkout/?$">
    Header always set Content-Security-Policy "frame-ancestors 'self' https://partner.example;"
  </LocationMatch>
</IfModule>

Nginx per-location:

# Default policy
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "frame-ancestors 'self';" always;

# For a specific route:
location = /embed/checkout {
    add_header Content-Security-Policy "frame-ancestors 'self' https://partner.example;" always;
}

WordPress conditional (PHP):

add_action('send_headers', function () {
    $csp = "frame-ancestors 'self';";
    if (isset($_SERVER['REQUEST_URI']) && preg_match('#^/embed/checkout/?$#', $_SERVER['REQUEST_URI'])) {
        $csp = "frame-ancestors 'self' https://partner.example;";
    }
    header("X-Frame-Options: SAMEORIGIN");
    header("Content-Security-Policy: {$csp}");
});

Multisite Notes (WordPress Network)

On multisite, keep Clickjacking Prevention in WordPress consistent via a network-activated MU-plugin. If one child site must be embeddable, add a per-site allowlist:

add_action('send_headers', function () {
    $allow = ["'self'"];

    // Example: allow framing only for site with blog_id 5
    if (function_exists('get_current_blog_id') && get_current_blog_id() === 5) {
        $allow[] = "https://partner.example";
    }

    header("X-Frame-Options: SAMEORIGIN");
    header("Content-Security-Policy: frame-ancestors " . implode(' ', $allow) . ";");
});

Legacy “Frame-Busting” JavaScript (Use Only as a Supplement)

JS solutions like the following are not reliable (headers win), but you may add them as an extra belt:

<script>
  if (top !== self) {
    // Replace the framing page with your page
    top.location = self.location;
  }
</script>

Headers are mandatory; treat JS as supplementary only.


Troubleshooting: When Embeds Break

  • Your site needs to be embedded in your own app? Use frame-ancestors 'self' https://app.yourbrand.com;.
  • Third-party widgets stopped working? Check their embed domain and add it to frame-ancestors. Many vendors use distinct CDN origins.
  • CSP errors in console? Tune frame-ancestors precisely; don’t confuse it with frame-src (older directive).
  • CDN in front (Cloudflare, etc.)? Verify headers are not being overwritten at the edge.

For ongoing assurance, run scans with your free tool: https://free.pentesttesting.com/.


Related Reading (Internal Links)

These posts complement Clickjacking Prevention in WordPress by addressing adjacent risks attackers often chain together.


New & Popular Services (How We Can Help)

Managed IT Services for Secure, Smooth Operations

If you want consistent patching, monitoring, and response without hiring a full team, explore Managed IT Services. We’ll keep security headers, TLS, and WordPress updates locked in—so Clickjacking Prevention in WordPress stays intact.

AI Application Cybersecurity (Models, APIs, & Plugins)

Building with AI? See AI Application Cybersecurity. We threat-model prompts, secure AI plugins, and apply CSP/headers on AI-driven UIs—Clickjacking Prevention in WordPress included where your WP site fronts an AI workflow.

Offer Cybersecurity to Your Clients (Partner/White-Label)

Agencies and MSPs: Offer Cybersecurity Service to Your Client with our white-label pentesting and hardening kits. We help you deliver Clickjacking Prevention in WordPress at scale.


Copy-Paste Recipes (Mini Cookbook)

Block all framing everywhere (strict):

X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none';

Allow your own domain only (typical WordPress):

X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self';

Allow your brand + a partner:

X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' https://partner.example;

Test quickly with cURL (spot-check):

curl -I https://your-site.example/ | egrep -i "x-frame-options|content-security-policy"

Final Takeaways

  • Default-deny with frame-ancestors 'self' (and X-Frame-Options: SAMEORIGIN as a backup).
  • Add precision allowlists only where business requires embedding.
  • Re-test headers every deployment; automate checks via CI or scheduled scans.
  • Use our free scanner for Website Security check before/after changes to validate Clickjacking Prevention in WordPress continuously.

Free Consultation

If you have any questions or need expert assistance, feel free to schedule a Free consultation with one of our security engineers>>

🔐 Frequently Asked Questions (FAQs)

Find answers to commonly asked questions about Clickjacking Prevention in WordPress.

Leave a Comment

Scroll to Top