f in x
HTTP Security Headers — Configure CSP, HSTS, and X-Frame to Protect Your Website
> cd .. / HUB_EDITORIALE
Sicurezza Informatica

HTTP Security Headers — Configure CSP, HSTS, and X-Frame to Protect Your Website

[2026-07-04] Author: Ing. Calogero Bono
Zenithby Meteora Web The operating system for your business. Social, clients, bookings and invoices in one platform. Gyms, barbers, professionals. Discover Zenith Free demo · no card

Your site is already on HTTPS, forms have CAPTCHA, passwords are hashed. Yet something feels off. The browser console shows warnings: missing Content Security Policy. A client calls because their site is rendered inside an iframe on an unknown domain. Or worse, you discover an XSS attack injected malicious code into product pages. This happens when HTTP security headers are neglected. At Meteora Web, we treat them like the deadbolt on your front door: skip it, and eventually someone breaks in. This guide covers the three essential headers — CSP, HSTS, and X-Frame-Options — with real examples, copy-paste code, and a practical cost-benefit approach.

Why Are HTTP Security Headers Your First Defense Against XSS and Clickjacking?

Imagine renting a shop. You install a nice sign, modern furniture, but leave the back door wide open. That's exactly what happens when you publish a site without security headers. A Cross-Site Scripting (XSS) or Clickjacking attack can bypass all other defenses if the browser receives no explicit instructions about what to load. HTTP headers are instructions sent by the server to the browser before any page content. Without them, the browser accepts any script, any iframe, any mixed content (HTTP/HTTPS) — an invitation for attackers.

Real example: A few months ago we inherited a WooCommerce e‑commerce store. The client complained about abandoned carts and unexplained slowness. Checking security headers, we found Content-Security-Policy was missing entirely. Result: the site loaded scripts from arbitrary sources, including a cryptocurrency miner injected via a vulnerable plugin. By configuring a proper CSP, we blocked the malicious script and improved load times by 30%. The cost? Zero. No new plugins, no investment — just configuration.

Sponsored Protocol

What to do right now:
Open your browser console on your site (F12 → Console). If you see red messages like "Refused to load the script... because it violates the following Content Security Policy directive…", you already have a CSP, but it's probably too strict. If you see nothing, you likely have no CSP at all — immediate red flag.

How Does Content-Security-Policy Work and How to Configure It Without Breaking the Site?

CSP is the king of security headers. It tells the browser: "Only load scripts, styles, images, fonts from these sources — everything else is blocked." If an attacker injects a malicious script, the browser blocks it outright. But an overly aggressive CSP will break your site (images not loading, analytics scripts blocked). The trick is balancing security and functionality.

Basic CSP structure

A CSP directive consists of a resource type (default-src, script-src, style-src, img-src, etc.) followed by one or more allowed origins. Here's an example for a WordPress site with Google Analytics and a jQuery CDN:

# In Nginx, inside server block
add_header Content-Security-Policy "
    default-src 'self';
    script-src 'self' https://www.googletagmanager.com https://ajax.googleapis.com 'unsafe-inline' 'unsafe-eval';
    style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
    img-src 'self' data: https://www.google-analytics.com https://www.googletagmanager.com;
    font-src 'self' https://fonts.gstatic.com;
    connect-src 'self' https://www.google-analytics.com;
    frame-src 'self' https://www.youtube.com;
    object-src 'none';
    base-uri 'self';
    form-action 'self';
";

Be careful: 'unsafe-inline' and 'unsafe-eval' reduce protection. In many WordPress sites they're necessary for plugins, but limit them as much as possible. For Laravel or Vue projects, we use server-generated nonces per request — more complex, but far more secure.

Sponsored Protocol

Practical steps to configure CSP on Nginx

  1. List all external resources your site loads: scripts, styles, images, fonts, iframes, etc. Use DevTools → Network tab, filter by third-party domains.
  2. Start with a report-only policy: Content-Security-Policy-Report-Only. The browser logs violations without blocking anything. Collect reports via a dedicated endpoint (e.g., report-uri.com).
  3. Analyze reports for 1–2 weeks. Add missing origins.
  4. Switch to enforcement mode: Content-Security-Policy.
  5. Repeat periodically, especially after theme or plugin updates.

Apache (.htaccess) example

<IfModule mod_headers.c>
  Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://www.googletagmanager.com 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https://www.google-analytics.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self'; frame-src 'self' https://www.youtube.com; object-src 'none'; base-uri 'self'; form-action 'self';"
</IfModule>

How to Enable HSTS and Why You Shouldn't Skip HTTP Strict Transport Security?

HSTS (HTTP Strict Transport Security) tells the browser: "From now on, always connect to this domain exclusively over HTTPS, even if the user types http://." Without HSTS, a man-in-the-middle (MITM) attack can intercept the very first HTTP request, redirect you to a malicious version, and steal credentials.

Sponsored Protocol

HSTS Configuration — The Key Parameters

The header has three main parameters:

  • max-age: duration in seconds. A common production value is 63072000 (2 years).
  • includeSubDomains: applies the rule to all subdomains (recommended if you use app.yourdomain.com, etc.).
  • preload: if you intend to submit your domain to browser preload lists (Chrome, Firefox, etc.), add this flag. However, once preloaded, it's practically irreversible for months. Ensure all subdomains support HTTPS and have no errors.
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

On Apache:

Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

Caution: Do not enable includeSubDomains if you have a subdomain that does not support HTTPS (e.g., an old separate blog). You could block access to that subdomain. Either prepare HTTPS for all subdomains first, or configure HSTS on the main domain alone.

Verify HSTS is active

Use the online tool hstspreload.org to test your domain. Enter your URL and you'll see if the header is present and parameters are correct. Alternatively, run curl -I https://www.yoursite.com and check for the strict-transport-security line.

X-Frame-Options: How to Prevent Your Site from Being Loaded in iframes on External Domains?

Clickjacking is an attack where a user is tricked into clicking an invisible element inside an iframe overlaid on another site. For example, an iframe with your login form is loaded on a phishing site, but the user thinks they're clicking a harmless button. The X-Frame-Options header tells the browser not to load the page in an iframe except from trusted origins.

Available options

  • DENY: no iframes allowed at all. The safest choice.
  • SAMEORIGIN: allowed only from iframes on the same origin. Useful if you use iframes yourself (e.g., embedding a map or internal form).
  • ALLOW-FROM uri (deprecated in many browsers). Today it's better to use Content-Security-Policy frame-ancestors for finer control.

Nginx configuration:

Sponsored Protocol

add_header X-Frame-Options "SAMEORIGIN" always;

Apache:

Header always set X-Frame-Options "SAMEORIGIN"

The modern alternative: Content-Security-Policy frame-ancestors

frame-ancestors is the CSP directive that supersedes X-Frame-Options. It lets you specify exactly which domains can embed your page in an iframe, supports wildcards and multiple origins. Example, allow only your domain and a trusted partner:

add_header Content-Security-Policy "frame-ancestors 'self' https://partner.com";

At Meteora Web, we recommend using frame-ancestors over X-Frame-Options if your audience uses modern browsers (all current ones), because it's more flexible. But for maximum backward compatibility (old browsers), include both.

How to Test and Monitor Security Headers with Free Tools?

Configuration alone is not enough: you must verify the headers are actually sent and aren't overwritten by a CDN, reverse proxy, or plugin. Here are the tools we use daily:

  • SecurityHeaders.com: provides a full report for each header, graded A to F. Aim for A.
  • Mozilla Observatory: similar but also tests for common vulnerabilities.
  • curl from the command line: curl -I https://yoursite.com | grep -i "content-security-policy\|strict-transport-security\|x-frame-options"
  • Browser console: as mentioned, CSP warnings are immediate.

Automate monitoring: integrate these tests into your CI/CD pipeline. We have a GitHub Actions job that runs nightly, sends an HTTPS request, and checks the headers. If something changes (e.g., after a deploy), we receive a notification. A small precaution that has saved more than one project from security regressions.

Sponsored Protocol

What to Do Now: Actionable Checklist to Secure Your Site

We've covered theory and configuration. Time to take action. Here are concrete steps to execute today:

  1. Run a securityheaders.com report for your domain. Identify missing or misconfigured headers.
  2. Enable HSTS with max-age of at least 6 months (recommended 2 years), includeSubDomains if safe, and verify on hstspreload.org.
  3. Set X-Frame-Options to SAMEORIGIN (or DENY if you don't use iframes) and, in parallel, add frame-ancestors 'self' to your CSP.
  4. Build a CSP in report-only mode. Collect reports for 1–2 weeks using a free endpoint like report-uri.com. Add missing origins, then switch to enforcing.
  5. Verify nothing is broken after configuration: navigate key pages (cart, checkout, forms) and check the browser console for CSP violations.
  6. Re-run securityheaders.com and aim for an A grade. If you get B or C, fix the reported issues.

At Meteora Web, we do this for every new project, whether it's a WooCommerce store or a Laravel web app. Security headers are not an add-on — they are the foundation. A client we work with, a well-known clothing brand, fixed a clickjacking problem on a promotional page simply by adding X-Frame-Options SAMEORIGIN. Result: no traffic loss, zero reputational damage. Cost? Zero. The risk avoided? Potentially millions in damages.

For a deeper dive into overall web security, check out our pillar guide on web security for developers.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()