Security & SSL

How to Configure HTTP Security Headers on Your Server

A step-by-step guide to adding the most important HTTP security headers in Apache and Nginx to protect your site from common web attacks.

A close-up of a chain link fence with padlocks securing it, symbolizing high security outdoors.

HTTP security headers are instructions your server sends to the browser, telling it how to behave when loading your site. Setting them correctly protects against XSS, clickjacking, and content injection — without touching a single line of your PHP or HTML code.

In this guide you'll learn which headers matter, what each one does, and how to add them in Apache or Nginx in under thirty minutes.

Why HTTP Security Headers Matter

A site can have SSL enabled, strong passwords, and up-to-date plugins and still be vulnerable if the browser doesn't know the rules for loading content. Security headers fill that gap:

  • They prevent external pages from embedding your site in an <iframe> (clickjacking).
  • They tell the browser to only execute scripts from origins you approve (XSS).
  • They enforce HTTPS connections even if a user types http://.
  • They stop the browser from "guessing" file types and executing malicious code disguised as an image.

Google checks these during Lighthouse audits, and tools like securityheaders.com assign a grade from A+ to F. A public F rating damages trust and SEO.

The Six Essential Headers

1. Strict-Transport-Security (HSTS)

Forces HTTPS for a defined period. Once the browser sees this header, it will never connect via HTTP during that time, even if the user types the URL without https://.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

max-age=31536000 equals 12 months. Start with a shorter value (86400 = 1 day) while testing, then increase it when everything works. Learn more about HSTS in our SSL security guide.

2. Content-Security-Policy (CSP)

Defines where the browser can load resources from: scripts, styles, images, fonts. It's the most powerful defense against XSS.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.yourdomain.com; img-src 'self' data:

CSP requires you to inventory your resources before enabling it. Use Content-Security-Policy-Report-Only first to detect blocks without breaking anything.

3. X-Frame-Options

Prevents your site from being loaded inside an <iframe> on another domain, blocking clickjacking attacks.

X-Frame-Options: SAMEORIGIN

If you don't need iframes from external domains, use DENY for complete protection.

4. X-Content-Type-Options

Prevents "MIME sniffing": the browser won't try to guess the file type and execute content that isn't what your server declared.

X-Content-Type-Options: nosniff

5. Referrer-Policy

Controls what origin URL information is sent when a user follows a link to another site. Protects internal paths and sensitive parameters.

Referrer-Policy: strict-origin-when-cross-origin

6. Permissions-Policy

Replaces Feature-Policy. Allows you to disable access to browser APIs (camera, microphone, geolocation) that your site doesn't need.

Permissions-Policy: camera=(), microphone=(), geolocation=()

How to Add Them in Apache

Edit your .htaccess file or the VirtualHost configuration (/etc/httpd/conf.d/yourdomain.conf):

<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
  Header always set Content-Security-Policy "default-src 'self';"
</IfModule>

Enable the module if it isn't active:

a2enmod headers   # Debian/Ubuntu
# On CentOS/AlmaLinux mod_headers is already active

Reload Apache to apply the changes:

systemctl reload httpd   # or apache2 on Ubuntu

How to Add Them in Nginx

Inside the server block of your configuration file (/etc/nginx/sites-available/yourdomain):

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self';" always;

Check the syntax and reload:

nginx -t && systemctl reload nginx

The always keyword is important in Nginx: it ensures headers are sent even on error responses (4xx, 5xx).

Verifying Your Headers Are Active

Once the changes are applied, verify with:

  • curl: curl -I https://yourdomain.com — displays headers in the terminal.
  • securityheaders.com — visual A+ to F grade with a description of each header.
  • Google Lighthouse — built-in audit in Chrome DevTools, "Best Practices" tab.

Aim for an A or A+ grade. If you see CSP warnings, use report-only mode to adjust before blocking.

If you're on shared hosting and can't edit server configuration, the team at elenlace.com can apply these headers within the limits of your plan or migrate your site to an environment with full access.

Key Takeaways

  • HTTP security headers are your first line of browser-level defense — independent of your CMS or language.
  • HSTS enforces HTTPS; CSP blocks XSS; X-Frame-Options stops clickjacking; nosniff prevents MIME sniffing.
  • In Apache, configure them with mod_headers in .htaccess or VirtualHost; in Nginx with add_header directives.
  • Always test CSP in report-only mode before switching to enforce mode in production.
  • Verify with securityheaders.com or curl -I that the headers reach the browser.

Can't edit your server configuration directly? At elenlace.com we offer hosting and technical management plans where we configure these headers for you and audit your entire site.

FAQ

Can I configure security headers on shared hosting?

It depends on your provider. Most allow .htaccess on Apache, which is enough for the basic headers. Advanced CSP and the HSTS preload directive may require access to the VirtualHost configuration, which is typically only available on VPS or dedicated servers.

Do security headers affect my site's speed?

Not in any meaningful way. They are text lines added to the HTTP response — their size is fractions of a kilobyte. The only possible impact is a strict CSP that blocks external resources your site tries to load, which is a configuration issue, not a performance one.

What happens if I enable HSTS with preload and then need to go back to HTTP?

It's very difficult to reverse. Once a domain is added to browser preload lists, users won't be able to connect via HTTP for the duration of the max-age, even if you remove the header. That's why you should start with a short max-age (86400) and without preload, only increasing it when you're certain HTTPS is permanent.

Does CSP work with WordPress?

Yes, but it takes extra effort. WordPress, its plugins, and themes load scripts, styles, and images from multiple origins. You need to build the policy using report-only mode first, collect violation reports, and then craft a policy that allows everything legitimate. Plugins like CSP with Google Analytics can simplify the process.

Useful resources

Other providers and guides worth comparing:

← All