Back to tutorials
Tutorial

cPanel Security Headers Setup Guide Tutorial (2026): HSTS, CSP, and Safe Defaults for Apache or LiteSpeed

cPanel security headers setup guide tutorial for HSTS, CSP, and safer defaults on Apache/LiteSpeed without breaking WordPress.

By Anurag Singh
Updated on Sep 26, 2026
Category: Tutorial
Share article
cPanel Security Headers Setup Guide Tutorial (2026): HSTS, CSP, and Safe Defaults for Apache or LiteSpeed

Most cPanel hardening happens at the edge: TLS, SSH, firewall rules, and account isolation. Many compromises still start in the browser. If you ship pages without Content-Security-Policy, allow loose framing rules, or skip HSTS, a small front-end bug can turn into session theft or an admin takeover.

This cPanel security headers setup guide tutorial shows how to add modern HTTP security headers in WHM/cPanel for Apache or LiteSpeed. You’ll also learn how to verify headers reliably. We’ll cover how to avoid the WordPress/plugin breakage that catches many admins.

The steps below target cPanel & WHM servers hosting many sites. If you run reseller hosting, you’ll learn how to set sensible defaults. You won’t need to edit every VirtualHost by hand.

Before you change anything: know your web stack and risk points

Confirm two details before you touch headers:

  • Web server: Apache (EA4) or LiteSpeed (often installed as a drop-in replacement).
  • Where SSL terminates: typically at Apache/LiteSpeed on the server. If you proxy via a CDN, header behavior can differ.

On the server, confirm what’s actually running:

httpd -V 2>/dev/null | head
/usr/local/lsws/bin/lshttpd -v 2>/dev/null

If LiteSpeed is installed, you can manage headers in LiteSpeed WebAdmin. You can also use Apache-compatible directives.

LiteSpeed supports most Apache header directives. In practice, the Apache-style approach below works on Apache. It usually works on LiteSpeed too.

Shared hosting planning note: aim for defaults that raise the floor. Avoid breaking dashboards, payment flows, WordPress editors, or common analytics tags.

Prerequisites checklist (do these first to prevent surprises)

  • Backups: take a snapshot or at least a config backup before touching global includes.
  • Staging test domain: pick one low-traffic domain on the server to validate headers.
  • Root access: SSH as root and WHM access.
  • HTTPS working already: don’t set HSTS until TLS is stable for the domain.

If you want an easy rollback plan, take a snapshot before changes. Keep an offsite copy too.

If you don’t already have a routine for this, follow: VPS Snapshot Tutorial (2026).

If you’re standing up a new hosting node or migrating clients, a HostMyCode VPS fits cPanel/LiteSpeed workloads where you want root-level control over headers, ModSecurity, and per-account limits.

Pick your header strategy: global defaults vs per-domain

cPanel supports Apache “include” files that persist across rebuilds. Use those for global defaults.

For exceptions (one app that needs a different CSP), use per-vhost includes.

  • Global includes (recommended): apply to all vhosts and survive /scripts/rebuildhttpdconf.
  • Per-domain includes: override for a specific site when a strict CSP breaks something.

On cPanel, the persistent include directories are usually:

  • /etc/apache2/conf.d/includes/ (common location)
  • /etc/apache2/conf.d/userdata/ (per-user/per-domain snippets)

We’ll use /etc/apache2/conf.d/includes/ for global headers. It’s straightforward and stays consistent across rebuilds.

Step 1: Enable the Apache modules you need (headers + rewrite)

Most cPanel EA4 installs already have mod_headers and mod_rewrite. Still, verify before you write config.

httpd -M | egrep 'headers_module|rewrite_module'

If headers_module is missing, enable it in WHM:

  1. WHM → EasyApache 4
  2. Apache Modules → search for headers
  3. Install/enable → Provision

LiteSpeed users: LiteSpeed typically honors Apache header directives. Still, confirm LSWS is configured to read Apache vhost configs.

Step 2: Create a global include file for security headers

Put your defaults in a dedicated file. This makes changes easier to track and revert.

sudo mkdir -p /etc/apache2/conf.d/includes
sudo nano /etc/apache2/conf.d/includes/security-headers.conf

Paste this baseline. It’s intentionally conservative for mixed WordPress + custom sites. It still reduces browser-facing risk.

<IfModule mod_headers.c>
  # 1) Stop MIME sniffing
  Header always set X-Content-Type-Options "nosniff"

  # 2) Reduce referrer leakage (good default for most sites)
  Header always set Referrer-Policy "strict-origin-when-cross-origin"

  # 3) Permissions Policy: disable features you rarely want on shared hosting
  # Adjust per site if you host apps needing camera/mic/geo.
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

  # 4) Clickjacking protection (modern browsers prefer CSP frame-ancestors; keep both)
  Header always set X-Frame-Options "SAMEORIGIN"

  # 5) Basic XSS protection header (legacy, but harmless)
  Header always set X-XSS-Protection "0"

  # 6) HSTS: DO NOT enable globally unless every domain is stable on HTTPS.
  # Leave commented here; enable per-domain after validation.
  # Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" env=HTTPS

  # 7) CSP baseline: start in Report-Only mode first (per-domain is better than global)
  # Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; font-src 'self' data: https:; frame-ancestors 'self'; base-uri 'self'" 
</IfModule>

Those defaults include a few intentional guardrails:

  • HSTS is commented out because enabling it globally on a cPanel server can strand HTTP-only domains. Browsers also cache HSTS aggressively.
  • CSP is commented out because CSP works best when you tune it per application. Roll it out in Report-Only first, then enforce it.
  • X-XSS-Protection is set to 0 because modern browsers ignore it, and older behavior can cause edge-case issues.

Step 3: Rebuild Apache config (the cPanel-safe way) and reload

On cPanel servers, don’t hand-edit /etc/apache2/conf/httpd.conf. cPanel regenerates it.

Rebuild and reload instead:

/scripts/rebuildhttpdconf
systemctl reload httpd

If you run LiteSpeed, reload LiteSpeed instead:

systemctl reload lsws 2>/dev/null || /usr/local/lsws/bin/lswsctrl reload

Run a syntax check before you reload. It saves time when there’s a typo:

apachectl configtest

Step 4: Verify headers for one domain (curl + browser devtools)

From your workstation or the server, check the response headers:

curl -I https://example.com | egrep -i 'x-content-type-options|referrer-policy|permissions-policy|x-frame-options|strict-transport-security|content-security-policy'

At minimum, you should see:

  • X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy: ...
  • X-Frame-Options: SAMEORIGIN

Also open DevTools → Network → click the main document → Response Headers. Look for duplicates or conflicting values.

WordPress plugins and CDN rules often introduce duplicates.

Step 5: Roll out HSTS safely (per-domain first, then consider wider scope)

HSTS tells browsers to stop using HTTP for a site. It’s excellent once HTTPS is stable.

It’s painful if you enable it too early.

Start per-domain using cPanel’s userdata include mechanism. For a single domain, the include path usually looks like this (replace placeholders):

/etc/apache2/conf.d/userdata/std/2_4/USERNAME/DOMAIN.TLD/

Create the directory and a file like hsts.conf:

sudo mkdir -p /etc/apache2/conf.d/userdata/std/2_4/username/example.com
sudo nano /etc/apache2/conf.d/userdata/std/2_4/username/example.com/hsts.conf

Add:

<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=15552000" env=HTTPS
</IfModule>

Then apply userdata includes and rebuild:

/scripts/ensure_vhost_includes --user=username --domain=example.com
/scripts/rebuildhttpdconf
systemctl reload httpd

Why no includeSubDomains yet? cPanel servers often expose mail., cpanel., webmail., or legacy subdomains. Confirm they’re HTTPS-clean before you force a browser to use TLS for everything.

If you need to sort out certificate issuance or stuck renewals before HSTS, see: cPanel AutoSSL troubleshooting.

Step 6: Add a CSP the way you won’t regret (Report-Only → tune → enforce)

CSP breaks sites when you skip the rollout process. Treat it like any change: stage it, test it, then enforce it.

  1. Start with Content-Security-Policy-Report-Only.
  2. Collect violations while real users browse.
  3. Tighten the policy.
  4. Switch to enforced Content-Security-Policy.

On shared hosting, keep CSP per-domain. Use the same userdata include approach as HSTS.

Create:

sudo nano /etc/apache2/conf.d/userdata/std/2_4/username/example.com/csp-report-only.conf

Start with a practical WordPress-friendly policy. It avoids immediate outages.

It’s not “maximum security,” but it’s a sane baseline you can tighten:

<IfModule mod_headers.c>
  Header always set Content-Security-Policy-Report-Only "default-src 'self'; base-uri 'self'; frame-ancestors 'self'; object-src 'none'; img-src 'self' data: https:; font-src 'self' data: https:; style-src 'self' 'unsafe-inline' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; connect-src 'self' https:"
</IfModule>

Apply and reload:

/scripts/ensure_vhost_includes --user=username --domain=example.com
/scripts/rebuildhttpdconf
systemctl reload httpd

Now use the site like a real user. Watch the browser console for CSP warnings:

  • Log in to /wp-admin
  • Edit a post in the block editor
  • Run checkout if it’s WooCommerce
  • Load any page builder UI if installed

If you see blocked scripts or connections, add the specific sources you need. For example, allow a payment gateway domain.

Avoid opening the policy with *.

Once it’s stable, switch to enforced CSP by changing the header name to Content-Security-Policy. Then remove allowances you don’t need.

In many environments, 'unsafe-eval' is a good first candidate to drop.

Step 7: Add COOP/COEP/CORP only when you know the app needs it

You’ll find lots of advice to enable COOP/COEP everywhere. On multi-tenant hosting, that can break embeds, some analytics, and cross-origin resources.

If you run a single-tenant application that benefits from cross-origin isolation (rare for typical shared WordPress hosting), test on that one domain first:

<IfModule mod_headers.c>
  Header always set Cross-Origin-Opener-Policy "same-origin"
  Header always set Cross-Origin-Resource-Policy "same-site"
</IfModule>

For most cPanel hosting servers, the earlier baseline plus per-domain CSP/HSTS delivers the meaningful wins. It also causes less collateral damage.

Common pitfalls (and how to debug them fast)

  • Duplicate headers: A WordPress security plugin may set headers in PHP. Prefer server-level headers, then disable duplicates in the plugin.
  • HSTS enabled too early: If a domain’s SSL breaks later, browsers won’t fall back to HTTP. Start with a smaller max-age (like 1 day) during the first week.
  • CSP blocks admin UI: Keep CSP per-domain, and test wp-admin thoroughly before enforcement.
  • Mixed content: CSP often exposes mixed content you didn’t notice. Fix URLs or enforce HTTPS at the app level.

If you’re chasing mixed content and redirect loops after changing HTTPS behavior, use: HTTPS redirect troubleshooting.

Practical hardening checklist for a hosting server running cPanel

  • Global headers baseline applied via /etc/apache2/conf.d/includes/security-headers.conf
  • HSTS enabled per domain after SSL is stable (max-age first, then consider includeSubDomains)
  • CSP rolled out per domain using Report-Only, then enforced
  • Verify with curl -I and DevTools; remove duplicates
  • Don’t break control panel subdomains; test cpanel., webmail., mail. where applicable

Security headers don’t replace server hardening. They complement it.

If SSH, sudo, and firewall rules still need work, start here: Server hardening for web hosting.

Where to place these changes if you’re managing many servers

If you manage multiple cPanel nodes, treat headers as part of provisioning. On unmanaged servers, you’ll apply it yourself.

On managed infrastructure, your provider should implement safe defaults. They should also handle exceptions cleanly.

If you want cPanel-grade control with less day-to-day admin work, managed VPS hosting is often a good fit for agencies and resellers. You still set the policy.

You just don’t have to babysit rebuilds and service reload order.

Need a hosting node where you can set security headers, tune Apache/LiteSpeed, and keep reliable rollback options? Start with a HostMyCode VPS, or hand the operational work to managed VPS hosting for production cPanel stacks.

FAQ

Should I enable HSTS globally on a cPanel server?

Usually no. cPanel servers often host many domains at different maturity levels. Enable HSTS per-domain after verifying SSL is stable for the apex and required subdomains.

Will a CSP break WordPress?

A strict CSP can. Start with Content-Security-Policy-Report-Only, fix violations, then enforce. Keep it per-domain so one problematic site doesn’t impact others.

Where do I add headers so cPanel won’t overwrite them?

Use cPanel-safe include paths such as /etc/apache2/conf.d/includes/ for global defaults and /etc/apache2/conf.d/userdata/ for per-domain overrides, then rebuild with /scripts/rebuildhttpdconf.

How do I check whether my headers are actually being served?

Use curl -I https://domain for a quick read, and confirm in the browser DevTools Network tab. Also check that you don’t have duplicate or conflicting headers from plugins/CDN rules.

What’s a safe minimum set of security headers?

On most hosting sites: X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and clickjacking protection (X-Frame-Options plus CSP frame-ancestors when you deploy CSP). Add HSTS only after HTTPS is solid.

Summary: a safer browser boundary without breaking customer sites

Security headers are one of the few upgrades you can deploy quickly and verify immediately. Use global defaults for low-risk headers.

Then roll out HSTS and CSP per domain with a cautious workflow.

Done right, you limit clickjacking, reduce XSS impact, and make HTTPS downgrade attempts much harder.

If you plan to standardize these settings across client sites, do it on infrastructure you control. A HostMyCode VPS gives you predictable config management, while managed VPS hosting can take the operational load off your team and keep your baseline consistent.