Security headers
This page is for administrators and hosting teams. HTTP security headers tell browsers to refuse common attacks: content sniffing, framing (clickjacking), leaking addresses in referrers, and access to the camera or microphone. Exponential sends five on every page, the administration included (13.9 Security headers and HTTPS).
Warning
.htaccess slows down every request. When .htaccess files are enabled (AllowOverride anything but None), let alone
used, Apache looks for them and reads and evaluates them on every request, in every directory of the path, and
page loading times go up drastically (measured). The only real fix is to switch the feature off for
the virtual host: AllowOverride None in the HTTPS virtual host, and the rules in the virtual host's own
configuration as mod_rewrite rules. That is far faster in production speed tests and well worth the time it takes
to optimize a production configuration. Switch over right away: copy the rules of the
example HTTPS virtual host into your virtual host (with the static cache, also
staticcache_offload.conf), set AllowOverride None, run apachectl configtest, reload Apache and
test the site. The same rules for other servers: nginx, LiteSpeed,
Caddy, IIS, Velocity (built in); where virtual host rules go in a control
panel: Plesk, cPanel, DirectAdmin, ISPConfig.
On LiteSpeed or OpenLiteSpeed, the server's own page cache can also answer anonymous visitors and crawlers without PHP: Page caching with LiteSpeed and OpenLiteSpeed.
Contents
The defaults
settings/site.ini [HTTPHeaderSettings] SecurityHeaders[]:
| Header | Default | Protects against |
|---|---|---|
X-Content-Type-Options | nosniff | browsers guessing a file's type and running it |
X-Frame-Options | SAMEORIGIN | the site being framed by another site |
Content-Security-Policy | frame-ancestors 'self' | the same, in the modern form |
Referrer-Policy | strict-origin-when-cross-origin | full addresses leaking to other sites |
Permissions-Policy | camera=(), microphone=(), payment=(), usb=() | pages using device features |
Strict-Transport-Security | empty (off; only ever sent over HTTPS) | see "HTTPS and HSTS" |
Pages answered from the kernel's HTTP cache carry the same headers.
Checking them
curl -sI https://www.example.gov/ | grep -i -E 'x-content-type|x-frame|referrer|permissions|content-security|strict-transport'
curl -sI https://admin.example.gov/user/login | grep -i -E 'x-frame|content-security'Expected: the five lines of the table (order may differ). Record the output as evidence in your security documentation after each change.
Changing one
Use an override, never settings/site.ini itself. Read the current value first:
./console exp:ini get 'site.ini/HTTPHeaderSettings/SecurityHeaders[Content-Security-Policy]' --allow-root-userExample: let a trusted editing host frame the administration:
# settings/override/site.ini.append.php
[HTTPHeaderSettings]
SecurityHeaders[Content-Security-Policy]=frame-ancestors 'self' https://edit.example.govAn empty value in an override drops a header; names and values that could split the response are ignored. Per path,
[HTTPHeaderSettings] HeaderList can still override any header. Clear the INI cache and reload PHP afterwards.
Static files
- Velocity sends four of them (all but the content security policy) on what it answers itself (static files,
resized images, error pages, redirects) through
settings/velocity.ini [ServerSettings] ResponseHeaders[]. - Apache and nginx send nothing extra on static files by themselves; add them with
mod_headers(Header always set X-Content-Type-Options "nosniff") oradd_header ... always;if you want them there. - SVG files from the storage get a sandboxing policy from the shipped
.htaccess_rootwhenmod_headersis present.
Related pages
- 13.9 Security headers and HTTPS
- Security and audit, 1
- TLS and HTTPS for hosts
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.