Securing your website is essential for protecting your business and users’ data. One of the key steps in web security is addressing common HTTP misconfigurations, especially in HTTP headers. In this guide, we’ll walk you through the best practices for configuring HTTP headers to help you safeguard your site and prevent potential vulnerabilities.
Contents
- 1 HTTP Header Security Guide
- 1.1 HTTP Strict Transport Security (HSTS)
- 1.2 Content Security Policy (CSP)
- 1.3 X-Frame-Options
- 1.4 X-XSS-Protection
- 1.5 X-Content-Type-Options
- 1.6 Referrer-Policy
- 1.7 Permissions-Policy
- 1.8 HTTP Public Key Pinning (HPKP)
- 1.9 Cross-Origin Resource Sharing (CORS)
- 1.10 Cross-Origin Embedder Policy (COEP)
- 1.11 Cross-Origin Opener Policy (COOP)
- 1.12 Cross-Origin Resource Policy (CORP)
- 1.13 Feature-Policy
- 1.14 Expect-CT
- 1.15 Timing-Allow-Origin
- 1.16 Server Signature
- 1.17 X-Recruiting
- 2 Conclusion
HTTP Header Security Guide
The HTTP headers provide control over how web content is handled, which helps to stop attacks and enforce secure communications between the server and the user. In this HTTP header security guide, we will cover the most important HTTP headers that you need to set to achieve a high level of security in your site.
Keep in mind that we will focus this on security headers, there’s a lot more headers that are not related to security, but if you want to check them out make sure to visit Mozilla’s MDN Web Docs.
HTTP Strict Transport Security (HSTS)
The first header in our HTTP header security guide is the famous HTTP Strict Transport Security (HSTS), which forces a secure (https) connection to the server. This prevents attacks like protocol downgrading and cookie hijacking.
Header example:
Strict-Transport-Security: max-age=3000000; includeSubDomains;
How to set HSTS in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Restart Apache:
systemctl restart apache2
Setting HSTS in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
Restart Nginx:
systemctl restart nginx
Content Security Policy (CSP)
Content Security Policy controls the resources that the user agent can load for a given page, preventing XSS and injection attacks.
Header example:
Content-Security-Policy: default-src 'self'; script-src 'self' 'https://trusted.domain.com'
How to set CSP in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'https://trusted.domain.com'"
Restart Apache:
systemctl restart apache2
Configuring CSP in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'https://trusted.cdn.com'";
Restart Nginx:
systemctl restart nginx
X-Frame-Options
Continuing with our HTTP header security guide, we have X-Frame-Options, a header that prevents a webpage from being framed to avoid clickjacking attacks.
Header example:
X-Frame-Options: DENY
Setting up X-Frame-Options in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set X-Frame-Options "DENY"
Restart Apache:
systemctl restart apache2
How to add X-Frame-Options to Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header X-Frame-Options "DENY";
Restart Nginx:
systemctl restart nginx
X-XSS-Protection
X-XSS-Protection provides cross-site scripting (XSS) filtering in browsers.
Header example:
X-XSS-Protection: 1; mode=block
Adding X-XSS-Protection to Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set X-XSS-Protection "1; mode=block"
Restart Apache:
systemctl restart apache2
How to configure X-XSS-Protection in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header X-XSS-Protection "1; mode=block";
Restart Nginx:
systemctl restart nginx
X-Content-Type-Options
The X-Content-Type-Options header is another important component of the HTTP header security guide, because it protects us from MIME type sniffing, which enhances security by enforcing the declared content type.
Header example:
X-Content-Type-Options: nosniff
Add X-Content-Type-Options to Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set X-Content-Type-Options "nosniff"
Restart Apache:
systemctl restart apache2
Enabling X-Content-Type-Options in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header X-Content-Type-Options "nosniff";
Restart Nginx:
systemctl restart nginx
Referrer-Policy
Referrer-Policy indicates how much referrer information should be included with requests.
Header example:
Referrer-Policy: no-referrer
Enable Referrer-Policy in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Referrer-Policy "no-referrer"
Restart Apache:
systemctl restart apache2
Set Referrer-Policy in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Referrer-Policy "no-referrer";
Restart Nginx:
systemctl restart nginx
Permissions-Policy
Permissions-Policy is the next step in this HTTP header security guide. Permissions-Policy controls access to features and APIs like geolocation, camera, and microphone.
Header example:
Permissions-Policy: geolocation=(), camera=(), microphone=()
Enable Permissions-Policy in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
Restart Apache:
systemctl restart apache2
How to add Permissions-Policy to Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Permissions-Policy "geolocation=(), camera=(), microphone=()";
Restart Nginx:
systemctl restart nginx
HTTP Public Key Pinning (HPKP)
HTTP Public Key Pinning is used to prevent MITM attacks by pinning the server’s public key. Keep in mind that this header is currently deprecated. We have decided to include it in our HTTP header security guide for legacy and documentation purposes.
Header example:
Public-Key-Pins: pin-sha256="base64+primary=="; max-age=2592000; includeSubDomains; report-uri="https://domain.com/hpkp-report"
Setting up HPKP is not recommended due to the risk of site lockout and other security issues. Modern browsers have deprecated support for it.
Cross-Origin Resource Sharing (CORS)
Cross-Origin Resource Sharing controls how resources on your site can be requested from another domain, this adds a layer of security for cross-origin interactions.
Header example:
Access-Control-Allow-Origin: https://trusted-origin-domain.com
How to configure Cross-Origin Resource Sharing in Apache
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Access-Control-Allow-Origin "https://trusted-origin-domain.com"
Restart Apache:
systemctl restart apache2
Adding Cross-Origin Resource Sharing to Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Access-Control-Allow-Origin "https://trusted-origin-domain.net";
Restart Nginx:
systemctl restart nginx
Cross-Origin Embedder Policy (COEP)
Cross-Origin Embedder Policy ensures that a document is allowed to load only resources that respect the same-origin policy or are marked as cross-origin available.
Header example:
Cross-Origin-Embedder-Policy: require-corp
Setting up Cross-Origin Embedder Policy in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Cross-Origin-Embedder-Policy "require-corp"
Restart Apache:
systemctl restart apache2
Enabling Cross-Origin Embedder Policy in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Cross-Origin-Embedder-Policy "require-corp";
Restart Nginx:
systemctl restart nginx
Cross-Origin Opener Policy (COOP)
Continuing with our HTTP header security guide, the next one is Cross-Origin Opener Policy, a header that helps to prevent documents from different origins from sharing a browsing context, which shields us against side-channel attacks.
Header example:
Cross-Origin-Opener-Policy: same-origin
Enable Cross-Origin Opener Policy in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Cross-Origin-Opener-Policy "same-origin"
Restart Apache:
systemctl restart apache2
How to configure Cross-Origin Opener Policy in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Cross-Origin-Opener-Policy "same-origin";
Restart Nginx:
systemctl restart nginx
Cross-Origin Resource Policy (CORP)
Cross-Origin Resource Policy is one of those must-have headers that we have included in this HTTP header security guide. This one restricts the resources a document can request, which increases security by enforcing same-origin or permitted cross-origin requests.
Header example:
Cross-Origin-Resource-Policy: same-origin
How to configure Cross-Origin Resource Policy in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Cross-Origin-Resource-Policy "same-origin"
Restart Apache:
systemctl restart apache2
How to enable Cross-Origin Resource Policy in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Cross-Origin-Resource-Policy "same-origin";
Restart Nginx:
systemctl restart nginx
Feature-Policy
Feature-Policy has been replaced by Permissions-Policy. It was used to control features and APIs usage on the website. Like HPKP, we have included it in our HTTP header security guide for legacy and documentation purposes.
Header example:
Feature-Policy: geolocation 'self'
Enable Feature-Policy in Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Feature-Policy "geolocation 'self'"
Restart Apache:
systemctl restart apache2
How to add Feature-Policy to Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Feature-Policy "geolocation 'self'";
Restart Nginx:
systemctl restart nginx
Expect-CT
Expect-CT allows sites to look into Certificate Transparency (CT) logs to detect and prevent certificate misissuance.
Header example:
Expect-CT: max-age=86400, enforce, report-uri="https://domain.com/report"
Add Expect-CT to Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Expect-CT "max-age=86400, enforce, report-uri='https://domain.com/report'"
Restart Apache:
systemctl restart apache2
How to configure Expect-CT in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Expect-CT "max-age=86400, enforce, report-uri='https://domain.com/report'";
Restart Nginx:
systemctl restart nginx
Timing-Allow-Origin
The Timing-Allow-Origin header specifies origins that are allowed to see resource timing data, which is used for performance monitoring.
Header example:
Timing-Allow-Origin: *
How to add Timing-Allow-Origin to Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set Timing-Allow-Origin "*"
Restart Apache:
systemctl restart apache2
Configure Timing-Allow-Origin in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header Timing-Allow-Origin "*";
Restart Nginx:
systemctl restart nginx
Server Signature
An HTTP header security guide can’t fulfill its purposes without mentioning the Server Signature, which hides server details in http responses to prevent information leakage.
How to configure Server Signature in Apache:
Edit Apache’s main config file:
nano /etc/apache2/apache2.conf
Add or modify the following lines:
ServerTokens Prod ServerSignature Off
Restart Apache:
systemctl restart apache2
Disable Server Signature in Nginx:
Edit Nginx’s main config file:
nano /etc/nginx/nginx.conf
Add or modify the following line inside the http block:
server_tokens off;
Restart Nginx:
systemctl restart nginx
X-Recruiting
To close our HTTP header security guide, we have the famous X-Recruiting header. This one is a non-standard header used to attract developers, often indicating job openings.
Header example:
X-Recruiting: We are hiring! Please visit https://my-domain.com/careers
How to add X-Recruiting-Header to Apache:
Edit your site’s config file:
nano /etc/apache2/sites-available/your_site.conf
Add the following inside the VirtualHost block:
Header always set X-Recruiting "We are hiring! Please visit https://my-domain.com/jobs"
Restart Apache:
systemctl restart apache2
Enable X-Recruiting-Header in Nginx:
Edit your site’s config file:
nano /etc/nginx/conf.d/your_site.conf
Add the following inside the server block:
add_header X-Recruiting "We are hiring! Please visit https://my-domain.com/jobs";
Restart Nginx:
systemctl restart nginx
Conclusion
This HTTP header security guide makes clear that setting up the HTTP headers is one of the most important steps to protect your website. Each header serves a specific purpose and, collectively, all of them will fortify your site’s defense against many threats.
Before setting them up, make sure that you carefully evaluate the implications of each header and configure them to fit your security requirements. Our HTTP header security guide also features links that will lead you to in-depth articles with more information on each header, be sure to check them out.