Skip to main content

Clickjacking protection is present

ab-002529 · site-health-check.security-posture.frame-protection
Severity: lowactive

Why it matters

Clickjacking embeds your site invisibly inside an attacker-controlled iframe. A user sees the attacker's page, but their clicks land on your site's buttons — authorizing transfers, changing account settings, or submitting forms without knowing. CWE-1021 (UI Redress Attack) and OWASP A05 (Security Misconfiguration) both classify missing frame protection as a preventable failure. The fix is cheap: one header. Without it, any page on your site that performs sensitive actions is vulnerable to this class of social-engineering attack targeting legitimate authenticated sessions.

Severity rationale

Low because clickjacking requires the victim to be tricked into visiting a malicious page, reducing realistic attack surface, but zero mitigation headers make it trivially exploitable when targeted.

Remediation

Add either X-Frame-Options or a CSP frame-ancestors directive — both protect against clickjacking, and they can coexist for broader browser coverage:

# nginx — both headers
add_header X-Frame-Options "DENY" always;
add_header Content-Security-Policy "frame-ancestors 'self'" always;

In Next.js next.config.js:

{ key: 'X-Frame-Options', value: 'DENY' }

Use DENY if your site never embeds itself in iframes. Use SAMEORIGIN if it needs to be framed from the same origin (e.g., admin embedded in a dashboard). CSP frame-ancestors takes precedence in modern browsers; X-Frame-Options covers older ones.

Detection

  • ID: site-health-check.security-posture.frame-protection

  • Severity: low

  • What to look for: Enumerate all clickjacking protection mechanisms in the response: check for X-Frame-Options header (must be DENY or SAMEORIGIN), and check the Content-Security-Policy header for a frame-ancestors directive. Count how many of these 2 protection mechanisms are present.

  • Pass criteria: At least 1 of the following 2 protections is present: (a) X-Frame-Options header with value DENY or SAMEORIGIN, or (b) CSP header contains a frame-ancestors directive that is not set to *. Report which mechanism(s) were found.

  • Fail criteria: Neither X-Frame-Options header nor a CSP frame-ancestors directive is present in the response.

  • Skip (N/A) when: The response is a redirect (3xx status) rather than a final document response.

  • Detail on fail: "No clickjacking protection — missing both X-Frame-Options and CSP frame-ancestors"

  • Remediation: Clickjacking embeds your site in a hidden iframe to trick users into clicking. Prevent it with either header:

    X-Frame-Options: DENY
    

    Or the modern CSP approach:

    Content-Security-Policy: frame-ancestors 'self'
    

    In next.config.js headers(), add X-Frame-Options: DENY. Both can coexist — browsers that support CSP frame-ancestors will use it; older browsers fall back to X-Frame-Options.


External references

Taxons

History