Security Headers
Overview
Section titled “Overview”Security headers instruct browsers to enable built-in protections against common attacks like clickjacking, XSS, MIME sniffing, and protocol downgrade. OLS supports setting headers natively or via .htaccess with the LiteHTTPD module.
Essential Security Headers
Section titled “Essential Security Headers”| Header | Purpose |
|---|---|
Strict-Transport-Security | Force HTTPS connections (HSTS) |
X-Frame-Options | Prevent clickjacking |
X-Content-Type-Options | Prevent MIME type sniffing |
Content-Security-Policy | Control resource loading |
Referrer-Policy | Control referrer information |
Permissions-Policy | Restrict browser features |
X-XSS-Protection | Legacy XSS filter (deprecated but still useful) |
OLS Native Configuration
Section titled “OLS Native Configuration”Server-Level Headers
Section titled “Server-Level Headers”Apply headers to all virtual hosts in httpd_config.conf:
extraHeaders { set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" set X-Frame-Options "SAMEORIGIN" set X-Content-Type-Options "nosniff" set Referrer-Policy "strict-origin-when-cross-origin" set Permissions-Policy "camera=(), microphone=(), geolocation=()" set X-XSS-Protection "1; mode=block"}Per-VHost Headers
Section titled “Per-VHost Headers”In the virtual host configuration:
virtualhost example { ... extraHeaders { set Strict-Transport-Security "max-age=31536000; includeSubDomains" set X-Frame-Options "DENY" set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'" }}Per-Context Headers
Section titled “Per-Context Headers”context /api/ { ... extraHeaders { set Access-Control-Allow-Origin "https://example.com" set Access-Control-Allow-Methods "GET, POST, OPTIONS" set Access-Control-Allow-Headers "Content-Type, Authorization" }}.htaccess Headers (LiteHTTPD)
Section titled “.htaccess Headers (LiteHTTPD)”With the LiteHTTPD module, use standard Apache Header directives in .htaccess:
# Set headersHeader set X-Frame-Options "SAMEORIGIN"Header set X-Content-Type-Options "nosniff"Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"Header set Referrer-Policy "strict-origin-when-cross-origin"Header set Permissions-Policy "camera=(), microphone=(), geolocation=()"
# Append to existing headerHeader append X-Frame-Options "SAMEORIGIN"
# Remove a headerHeader unset X-Powered-ByHeader unset Server
# Conditional headerHeader set X-Robots-Tag "noindex, nofollow" env=stagingHeader Configuration Examples
Section titled “Header Configuration Examples”HSTS (HTTP Strict Transport Security)
Section titled “HSTS (HTTP Strict Transport Security)”Forces browsers to use HTTPS for all future requests to your domain:
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"max-age=31536000— remember for 1 yearincludeSubDomains— apply to all subdomainspreload— opt in to browser preload lists (submit at hstspreload.org)
Content Security Policy (CSP)
Section titled “Content Security Policy (CSP)”Controls which resources the browser is allowed to load:
# Basic restrictive policyHeader set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'"
# WordPress-friendly policyHeader set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'"Start with Content-Security-Policy-Report-Only to test without blocking:
Header set Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report"X-Frame-Options
Section titled “X-Frame-Options”Prevents your site from being embedded in iframes (clickjacking protection):
# Block all framingHeader set X-Frame-Options "DENY"
# Allow same-origin framing onlyHeader set X-Frame-Options "SAMEORIGIN"X-Content-Type-Options
Section titled “X-Content-Type-Options”Prevents browsers from MIME-sniffing a response away from the declared content type:
Header set X-Content-Type-Options "nosniff"Referrer-Policy
Section titled “Referrer-Policy”Controls how much referrer information is sent with requests:
# Send origin only on cross-origin requestsHeader set Referrer-Policy "strict-origin-when-cross-origin"
# Never send referrerHeader set Referrer-Policy "no-referrer"Permissions-Policy
Section titled “Permissions-Policy”Restricts browser features like camera, microphone, and geolocation:
Header set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()"Remove Information Disclosure Headers
Section titled “Remove Information Disclosure Headers”Header unset X-Powered-ByHeader unset ServerComplete Example
Section titled “Complete Example”OLS Native (httpd_config.conf)
Section titled “OLS Native (httpd_config.conf)”extraHeaders { set Strict-Transport-Security "max-age=31536000; includeSubDomains" set X-Frame-Options "SAMEORIGIN" set X-Content-Type-Options "nosniff" set Referrer-Policy "strict-origin-when-cross-origin" set Permissions-Policy "camera=(), microphone=(), geolocation=()" unset X-Powered-By}.htaccess (LiteHTTPD)
Section titled “.htaccess (LiteHTTPD)”Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"Header set X-Frame-Options "SAMEORIGIN"Header set X-Content-Type-Options "nosniff"Header set Referrer-Policy "strict-origin-when-cross-origin"Header set Permissions-Policy "camera=(), microphone=(), geolocation=()"Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:"Header unset X-Powered-ByVerify Headers
Section titled “Verify Headers”curl -I https://example.comOr use online tools like securityheaders.com to scan your site and get a grade.
Troubleshooting
Section titled “Troubleshooting”Headers not appearing in response:
- For
.htaccess: verify the LiteHTTPD module is loaded andautoLoadHtaccessis enabled - For OLS native: check
extraHeadersis in the correct block (server, vhost, or context) - Restart OLS after configuration changes
CSP blocking legitimate resources:
- Use
Content-Security-Policy-Report-Onlyfirst - Check the browser console for CSP violation messages
- Add the blocked domain to the appropriate directive