Key Points
- Use modern browser controls, such as CSP frame-ancestors, instead of X-Frame-Options to apply stronger and more flexible clickjacking protection across tenants.
- Align your policy with real application behavior by listing legitimate embeds first, so your allow-lists include only what business workflows require.
- Validate protections regularly in staging by checking headers and testing framing attempts with browser tools to confirm that enforcement works as intended.
- Avoid using JavaScript frame-busters or other fragile methods since attackers can easily bypass these defenses.
- Maintain ongoing proof of compliance with a monthly evidence packet that includes header scan results, blocked framing attempts, and approved exceptions managed under change control.
Clickjacking is a UI redress attack that tricks people into clicking hidden or disguised elements on a page, often through a malicious or unintended iframe. The right way to block it is at the browser level using security headers, mainly CSP frame-ancestors for modern coverage and X-Frame-Options for legacy support.
To keep clickjacking protection consistent across tenants, you need a clear policy, scoped allow-lists, reliable validation tests, and ongoing monitoring with evidence you can share with stakeholders. This guide explains how to build and maintain effective clickjacking protection across tenant environments.
Methods to prove clickjacking protection across tenants
Before you apply or test any protections, ensure the basics are in place.
📌 General prerequisites:
- An inventory of applications, known embedding partners, and any client portals that must support framing.
- The ability to set or adjust response headers at the application layer or through a reverse proxy.
- Access to a staging domain or environment for safe header testing.
- Basic tools for traffic capture or automated header scans to verify results.
- A shared workspace or repository for storing monthly evidence packets and related documentation.
Method 1: Inventory real embed requirements
Before applying any clickjacking protections, identify which applications or pages are legitimately intended to be embedded. This inventory serves as your ground truth. It ensures that valid use cases remain functional and prevents unnecessary blocking during rollout.
Steps:
- Review all applications and pages, and list those designed to be embedded. Look for <iframe> usage, widgets, dashboards, or client portals.
- Document which external domains are allowed to embed each page.
- For every embeddable page, note the business reason for framing it.
- Store the information in a shared configuration file, spreadsheet, or internal wiki. Include:
- Page URLs
- Allowed domains
- Notes on framing behavior
Method 2: Select your primary mitigation
Next, decide which technical control will enforce your clickjacking protection. The goal is to apply a consistent, browser-compatible defense across all tenants.
Steps:
- Use Content-Security-Policy: frame-ancestors as your main control. It allows you to specify exactly which domains can embed your content and supports granular allow-lists for trusted tenants or partners.
- Keep X-Frame-Options in place as a fallback for browsers that don’t fully support Content Security Policy (CSP).
- Record your reasoning, noting why CSP is your main control and XFO is used for legacy coverage. Include sample configurations and compatibility notes.
- Store this documentation in a shared configuration file or repository, so all app teams follow the same standard.
Method 3: Author a minimal, specific policy
With your inventory complete and mitigation method chosen, it’s time to write a precise CSP that enforces clickjacking protection. Apply the principle of least privilege. Allow only the trusted domains identified in your inventory and block everything else.
Steps:
- Start with the most restrictive baseline:
Content-Security-Policy: frame-ancestors ‘self’;
This limits framing to your own domain and blocks all external sources by default.
- Gradually extend the policy only as needed to include verified domains:
Content-Security-Policy: frame-ancestors ‘self’https://portal.example.com;
- Avoid wildcards. Don’t use * unless absolutely necessary, and if you must, scope it tightly.
- If you need to add an exception, document it with:
- Purpose and expiration date
- Change record or ticket number
- Responsible team or approver
Method 4: Validate with simple framing tests
After defining your policies, you must prove that they behave correctly under real browser conditions. This method verifies how your pages respond when framed from both allowed and disallowed origins to ensure only approved domains can display your content.
Steps:
- Create a minimal HTML test page on an external domain that embeds your target page using an <iframe>. Host this page on both allowed and disallowed domains.
- Open your staging URLs in Chrome, Edge, or Firefox and observe the behavior. Allowed domains should load. Disallowed ones should be blocked.
- In the browser console or network tab, look for messages such as:
Refused to display ‘https://app.example.com’ina frame because itset’X-Frame-Options’to’SAMEORIGIN’.
or
Refused to frame ‘https://app.example.com’ because an ancestor violates the following Content Security Policy directive: “frame-ancestors ‘self'”.
- Capture evidence for records, including:
- Screenshots of both successful and blocked loads
- Response headers
- Console messages
- Record which domains passed or failed and document any unexpected results for follow-up.
Method 5: Handle edge cases without weakening policy
Some tenants or integrations may require exceptions, but relaxing protections globally is risky. Handle these cases carefully to avoid weakening your security posture.
Steps:
- Avoid JavaScript frame-busting. Don’t rely on code like:
if (top !== self) top.location = self.location;
It’s easily bypassed and shouldn’t replace header-based controls.
- For legitimate third-party embeds, create tightly scoped allow-lists that permit only specific domains and avoid using wildcards.
- For legacy browsers, keep your X-Frame-Options setting aligned with your CSP to avoid conflicting behavior.
- Each time you add an exception, re-run your framing validation (Method 4) to confirm that the allowance works correctly while other restrictions stay in place.
- Log every exception. Record who approved it, when, and why. Assign an expiration or review date and record it in your policy register for audit tracking purposes.
Method 6: Roll out safely and monitor
After final testing, deploy your clickjacking protections to production, but do it carefully. A gradual rollout with active monitoring helps prevent breaking legitimate integrations.
Steps:
- Deploy CSP and XFO headers behind a feature flag or configuration toggle so they can be disabled quickly if needed.
- Start in staging, then expand to a small group of tenants or internal users before a full rollout.
- Monitor application behavior:
- Check logs for related errors.
- Look for blocked iframes or empty embeds.
- Track client feedback through support channels.
- Use browser console data and analytics to confirm impact and respond quickly to any breakage reports.
- Keep a short rollback plan that lists:
- The config toggle or setting location
- Deployment steps
- Escalation contacts
- Once the rollout runs smoothly for several days without any issues, mark it as complete and update your documentation.
Method 7: Scan for drift and regressions
Even well-deployed protections can weaken over time due to updates or configuration drift. This method helps ensure your policies stay consistent and effective.
Steps:
- Document the expected CSP and XFO headers for each domain or tenant.
- Set up weekly scans of public endpoints using tools like curl, a security scanner, or a simple script.
- Verify that frame-ancestors or X-Frame-Options headers are present and match the expected values, with no new wildcards or unapproved domains.
- If headers are missing or incorrect, open a ticket that includes the affected domain, owner, discovery date, and expected policy.
- Keep exceptions limited, documented, and time-bound. Review them regularly and close any that are outdated.
Method 8: Publish a monthly evidence packet
Finally, close the loop with documentation and reporting. A monthly evidence packet turns your ongoing validation work into formal proof of compliance and governance.
Steps:
- Compile header scan summaries from the past month, listing:
- Tenant domain
- Header values
- Scan status (pass/fail)
- Timestamp
- Include examples of blocked framing attempts or CSP violation reports from your report-to endpoint, showing:
- Test domain and URL
- Browser console message
- Screenshot of the blocked iframe
- Document all approved exceptions with:
- Domain
- Reason and expiry date
- Linked change record or approval ticket
- Add screenshots of working embeds to confirm that legitimate framing continues to function as expected.
- Record any policy changes or redeployments made that month. Reference related tickets or commits.
- Tie the evidence packet to a standing change-control record or Jira epic so auditors and clients can see governance in action.
- Store the packet in a central location (e.g., SharePoint, Confluence, or your ticketing system), tagged with tenant ID and reporting period.
Best practices summary table
Use this table to reinforce the key practices that support reliable, secure, and auditable clickjacking protection across tenants.
| Practice | Purpose | Value delivered |
| frame-ancestors as default | Adopt modern, granular anti-framing control. | Strong protection with fewer false blocks |
| Minimal allow-lists | Reduce attack surface. | Safer embeds without breakage |
| Staging-based tests | Validate behavior before rollout. | Confidence that protections work as intended before production |
| Weekly header scans | Detect drift or misconfigurations. | Early fixes and cleaner audits |
| Monthly evidence packet | Prove the control is working. | Clear QBR story and audit readiness. |
Automation touchpoint example
Automation reduces manual effort, catches issues early, and keeps protections consistent across tenants. Use scheduled jobs to enforce and verify clickjacking controls without relying on manual checks.
A typical setup looks like this:
- Nightly header check
- A scheduled job fetches response headers from all tenant URLs, confirming that Content-Security-Policy: frame-ancestors or X-Frame-Options is present and correct.
- Any mismatch or missing header is flagged automatically and logged for review.
- Weekly iframe test run
- Once a week, a test page attempts to embed tenant pages from both allowed and disallowed origins.
- The process captures pass or fail results, console messages, and screenshots to confirm that blocking and allowed behavior align with policy.
- Monthly evidence packet generation
- At the end of each month, a scheduled script compiles header scan logs, test results, and exception lists.
- The output is saved as a PDF or structured report and stored with the corresponding change record for audit reference.
NinjaOne integration
For teams managing multiple tenants and applications, automation fits naturally into existing NinjaOne workflows. Here’s how NinjaOne can support clickjacking protection and governance:
| Feature | Action |
| Scheduled automations | Use NinjaOne’s scheduled automations to run custom scripts that perform header checks across tenant URLs. Log results centrally with custom fields and the platform’s built-in activity logging. |
| Ticket/Alert generation | Automatically generate tickets or alerts in integrated PSA systems when scheduled checks detect issues, with the option to attach evidence directly to the related change or compliance tracking. |
| Tagging and custom fields | Apply flexible tagging and custom fields to categorize monitored endpoints and services by tenant and application, enabling easy tracking of exceptions, expirations, and compliance status. |
| Reporting and dashboards | Aggregate scan results and exception data in NinjaOne’s reporting and dashboard features, creating visual representations of governance activities ideal for quarterly business reviews and compliance tracking. |
Sustaining strong clickjacking protection with testing and evidence
Clickjacking protection doesn’t have to be complicated. When you use modern controls, test them in staging, and keep an eye out for drift, the process becomes simple and repeatable. Pairing CSP frame-ancestors with clear, minimal allow-lists and consistent evidence makes it easy to show that your safeguards work, and that they stay that way across every client environment.
Related topics:
