Skip to main content

HTTP security headers: set up HSTS, CSP and more

Published on July 9, 2026 10 min read

Learn what HTTP security headers like HSTS and CSP do and how to set them up safely through .htaccess on Plesk or a WordPress plugin, step by step.

Flat illustration of a person beside a large browser window with a shield and padlock, small cards drifting towards it like security layers and an orange arrow deflecting off it, in shades of blue with an orange accent.

Did a security scan such as securityheaders.com or the MDN HTTP Observatory report that your website is missing security headers? HTTP security headers like HSTS and CSP are short instructions that your server sends with every page, telling the browser how to handle your site safely. This article explains what the most important security headers do, which attacks they stop, and how to set them up through .htaccess on your Plesk hosting or with a WordPress plugin.

What are HTTP security headers?

Every time a visitor requests a page, your web server sends a set of HTTP response headers alongside the content. These are short lines that work in the background and control all sorts of things, from caching to the type of content. Security headers are a special group of them: they give the browser stricter rules about what is allowed to happen with your page.

Security headers do not replace safe code, strong passwords or updates. They add an extra layer of defence, often called defence in depth. If a flaw does slip into your site or a plugin, the headers often limit the damage an attacker can do.

Which attacks do security headers stop?

Each header targets a specific risk. These are the main ones:

  • Clickjacking: an attacker loads your page inside an invisible frame (iframe) on another site and tricks visitors into clicks they did not intend. Stopped by X-Frame-Options and CSP.
  • Cross-site scripting (XSS): malicious scripts injected into your page that run in your visitor's browser. Limited by Content-Security-Policy.
  • Downgrade attacks and SSL stripping: an attacker pushes the visitor back to an unencrypted http connection to eavesdrop. Stopped by HSTS.
  • MIME sniffing: the browser guesses the file type itself and runs, for example, an uploaded file as a script. Stopped by X-Content-Type-Options.
  • Leaking data through the referring URL: controlled with Referrer-Policy.
  • Unwanted use of camera, microphone or location: controlled with Permissions-Policy.

The most important security headers at a glance

The table below gives an overview. Underneath, you can read what each header does and which value is a good starting point.

Overview of the most important HTTP security headers and a safe starting value.
HeaderProtects againstRecommended starting value
Strict-Transport-SecurityDowngrade attacks, SSL strippingmax-age=63072000; includeSubDomains
Content-Security-PolicyXSS, code injection, clickjackingStart in report-only (see below)
X-Frame-OptionsClickjackingSAMEORIGIN
X-Content-Type-OptionsMIME sniffingnosniff
Referrer-PolicyLeaking URL datastrict-origin-when-cross-origin
Permissions-PolicyMisuse of browser featuresgeolocation=(), camera=(), microphone=()

Strict-Transport-Security (HSTS)

HSTS forces browsers to reach your site only over https, even if someone types http by mistake. The max-age value sets how long the browser remembers this, in seconds. With includeSubDomains the rule also applies to all your subdomains, and with the optional preload flag you can have your domain added to a list that is already built into browsers.

A widely used, safe value is max-age=63072000 (two years) with includeSubDomains. Important: a browser only accepts HSTS when the header is sent over https. At LJPc, HSTS is already switched on by default, see the section below.

Content-Security-Policy (CSP)

CSP is the most powerful header, but also the trickiest. It lets you decide exactly which sources (scripts, images, stylesheets) may load and from which domains. That makes CSP your strongest weapon against XSS. Its frame-ancestors directive also handles clickjacking and is the modern successor to X-Frame-Options.

Because a policy that is too strict can break your site, it is best to set CSP up in report-only mode first. We explain that approach step by step further down.

X-Frame-Options

This header decides whether your page may be loaded in an iframe on another site, protecting you against clickjacking. The value SAMEORIGIN allows framing only on your own domain, while DENY blocks it entirely. The old value ALLOW-FROM is obsolete and is ignored by modern browsers.

CSP frame-ancestors does the same thing, but with more control. You may set both: older browsers understand only X-Frame-Options, newer ones follow frame-ancestors.

X-Content-Type-Options

The only valid value is nosniff. It stops the browser from guessing what kind of file it receives. Without this header a browser can, for example, run an uploaded text file as HTML or a script, which makes XSS possible.

Referrer-Policy

This header controls how much of the previous URL is sent along when a visitor clicks through from your site. The value strict-origin-when-cross-origin sends the full address within your own site, but only your domain without the path to other sites. Modern browsers already use this as the default, but setting it explicitly makes your intent clear.

Permissions-Policy

With Permissions-Policy (the successor to Feature-Policy) you decide which browser features your page may use, such as camera, microphone and location. An empty list in brackets, for example camera=(), switches a feature off completely. Disable every feature your site does not need.

An outdated header you may still come across in scans is X-XSS-Protection. It is discouraged: do not set it any more, or give it the value 0. CSP has taken over its job.

What LJPc already handles for you: HSTS and OCSP stapling

As soon as an SSL certificate is activated on your website, LJPc switches HSTS on automatically, with a max-age of two years and includeSubDomains. OCSP stapling is enabled by default too. That last one speeds up the https handshake and is not a header you manage yourself. So you do not need to add the HSTS header yourself, and it is best not to add it through .htaccess either, because that risks a duplicate header.

HSTS only works when your site is genuinely reachable over https. So first make sure you have a valid SSL certificate. Every hosting package includes a free Let's Encrypt certificate that is issued and renewed automatically. Focus your own work on the other headers: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy.

Setting up security headers through .htaccess on Plesk

On Plesk hosting with Apache, the easiest way to add headers is through the .htaccess file in the httpdocs folder. Apache then sends the headers with every page. Work through these steps:

  1. Make a backup of your current .htaccess first, so you can always restore it.
  2. Open .htaccess in the Plesk file manager or over FTP/SFTP. If the file does not exist yet, create it in the httpdocs web root.
  3. Paste the block below at the top of the file and save it.
  4. Refresh your site and check that everything still works. Then test your headers (see further down).
<IfModule mod_headers.c>
    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 "geolocation=(), camera=(), microphone=()"
</IfModule>

The always keyword makes sure the header is sent on error pages too, such as a 404. The IfModule line prevents an error if the mod_headers module is ever inactive. HSTS is deliberately left out of this block, because LJPc already sends it. If you would rather not touch .htaccess, and your package gives you access to the Apache and nginx settings in Plesk, you can add the same lines in the field for additional Apache directives.

Setting up security headers in WordPress

If you would rather not edit .htaccess, you can use a plugin in WordPress. A popular, free option is Headers Security Advanced & HSTS WP, which adds the headers for you through a settings screen.

  1. In your WordPress dashboard, go to Plugins and then Add Plugin, and search for Headers Security Advanced.
  2. Install and activate the plugin.
  3. Open the plugin settings and switch on the headers you want: X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy.
  4. Leave HSTS switched off, because LJPc already sends it. That way you avoid a duplicate header.
  5. Be careful with the CSP option: only switch it on after you have tested it, otherwise scripts or styles may drop out.

Note: a plugin and an .htaccess rule can both send the same header. So pick one method per header, to avoid duplicate values.

Setting up Content-Security-Policy without breaking your site

CSP is the header that most often breaks something, because legitimate scripts or styles suddenly get blocked. WordPress in particular uses a lot of inline scripts and styles, so caution is needed. Take it in stages:

  1. Start with the report-only variant. It reports violations but does not block anything yet. In .htaccess that looks like this:
Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'"
  1. Visit your site and keep an eye on your browser console (F12, Console tab). Every blocked source appears there as a message.
  2. Add the sources you genuinely need to the right directive, for example the domain of your fonts or your analytics tool.
  3. Once everything works without messages, change Content-Security-Policy-Report-Only into Content-Security-Policy. The policy is now enforced.
  4. Optionally add frame-ancestors 'self' as a modern replacement for X-Frame-Options.

A strict CSP without 'unsafe-inline' is the safest, but in practice many WordPress themes need that exception for styles. So build your policy up gradually and test again after each change.

Checking that your headers work

After setting them up, you will want to be sure the headers are actually sent. There are three ways to do this:

  • Online scanners: securityheaders.com and the MDN HTTP Observatory give your site a grade and show which headers are missing.
  • Browser developer tools: open F12, go to the Network tab, reload the page and click the first request. Under Response Headers you can see the headers that were sent.
  • Command line: the command curl -I https://yourdomain.com requests just the headers.

Common problems

Common problems when setting up security headers and how to solve them.
ProblemCauseSolution
Header does not appearmod_headers is inactive or your site runs on a separate server configurationCheck that mod_headers is enabled, or contact support
Duplicate Strict-Transport-SecurityYou added HSTS yourself while LJPc already sends itRemove your own HSTS line
Site or parts of it stop workingA Content-Security-Policy that is too strict blocks scripts or stylesSet CSP back to report-only and add the missing sources
Header missing on error pagesYou used set instead of alwaysUse Header always set
Change is not visibleCaching in your browser or hostingClear the cache and test again, or test with curl

Cannot work it out, or want to be sure your headers are set correctly? Feel free to contact LJPc support and we will take a look with you.

Frequently asked questions

What are HTTP security headers?

They are short instructions that your web server sends with every page, telling the browser how to handle your site safely. Think of enforcing https, blocking framing and restricting scripts. Together they form an extra layer of security on top of safe code and updates.

Which security headers matter most?

The six you want on almost every site are Strict-Transport-Security (HSTS), Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy. Together they cover the most common risks, such as downgrade attacks, XSS and clickjacking.

Do I need to set up HSTS myself at LJPc?

No. LJPc switches HSTS on automatically as soon as an SSL certificate is activated on your site, with a max-age of two years and includeSubDomains. So do not add the header again yourself, or you will get a duplicate Strict-Transport-Security header.

Why does my site stop working after setting up Content-Security-Policy?

Usually the policy is too strict, which blocks legitimate scripts or styles. Set CSP to report-only mode first, check your browser console to see which sources are blocked, and add them. Only enforce the policy once everything works without messages.

How do I check my security headers?

Use an online scanner such as securityheaders.com or the MDN HTTP Observatory for a grade and an overview. In your browser, press F12 and open the Network tab to view the Response Headers, and with curl -I https://yourdomain.com you can request them on the command line.

Is X-XSS-Protection still needed?

No, that header is outdated and discouraged. Leave it out or give it the value 0. Content-Security-Policy now offers much better protection against XSS.

Prefer to talk to someone?

We are also happy to answer your questions personally. Schedule a free consultation or call us directly. We are glad to think along with you.

Stay up to date with recent developments! Subscribe and receive our newsletter Signing up... Thank you for subscribing! Something went wrong. Please try again later.