Copypasta HTTP security headers
Image icon by vectorjuice from FreePik

Copypasta HTTP security headers for your Apache website

While I was doing SEO for this blog in the past few couple of days, I’ve come across a set of HTTP security headers I’ve never heard of before. These are a set of HTTP headers that you can deploy on your website(s) to tell browsers how to interact with your site in a variety of situations, and they can help to prevent things like cross-site request forgery or iFrame injection XSS attacks from happening on your site, as well as improve your website(s) SEO score (apparently).

Needless to say, I immediately sought to implement them. If you’re looking for some settings that you can copy and paste right into your own web server, read on further.

1. Setting the HTTP headers in Apache

My website was hosted on Apache, so I added and enabled a configuration on Apache that applied to every VirtualHost on my server.

a. Applying HTTP headers globally (i.e. to every VirtualHost)

The following configuration file (global-headers.conf) was added to the /etc/apache2/conf-available folder:

/etc/apache2/conf-available/global-headers.conf

<IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
<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: microphone=(),camera=()
        Header always set Content-Security-Policy: "frame-ancestors 'self'"
        Header always set Strict-Transport-Security: max-age=31536000
</IfModule>

The configurations do the following:

  1. The <IfModule mod_rewrite.c> block redirects any HTTP URL to its HTTPS variant. This essentially means that there is no way to access any websites on the Apache server using HTTP, and it is important because we will be enabling the HSTS (HTTP Strict Transport Security) policy with our headers.
  2. The <IfModule mod_headers.c> block automatically adds the HTTP headers to all VirtualHosts, so that all the sites on your server will have this policy. You can override these policies in your individual VirtualHosts if you wish.

After the file was created, I ran the following command to add the configuration file to Apache:

$ sudo a2enconf global-headers

Of course, you’ll have to restart Apache for the changes to take effect.

$ service apache2 restart

If you like to override these settings in your individual VirtualHosts, you can do the following:

<VirtualHost *:443>
	...
	# Overrides the global Permissions-Policy with a different one for this virtual host.
	Header unset Permissions-Policy
	Header always set Permissions-Policy: camera=()
	...
</VirtualHost>

b. Applying HTTP headers to a single VirtualHost

If you only want to apply these settings to a single VirtualHost, you can just add it to the existing configurations in your VirtualHost settings:

<VirtualHost *:443>
	ServerName blog.terresquall.com
	DocumentRoot /var/www/blog.terresquall.com
	
	# Add the policy headers to all pages in the VirtualHost
	<IfModule mod_rewrite.c>
        	RewriteEngine on
        	RewriteCond %{HTTPS} off
        	RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
	</IfModule>
	<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: microphone=(),camera=()
        	Header always set Content-Security-Policy: "frame-ancestors 'self'"
        	Header always set Strict-Transport-Security: max-age=31536000
	</IfModule>
</VirtualHost>

Remember to restart Apache for the changes to take effect.

c. Applying the headers to .htaccess

You can also add the snippet to the .htaccess file in your web root. If you do, remember to test it right after! The changes apply as soon as you save your .htaccess file.

2. Setting the HTTP headers in PHP

If you don’t have access to your web server configuration files, you can also set the headers in your web files.

a. Applying HTTP headers in WordPress

For WordPress users, you can attach the following script to either the functions.php file of your theme (I recommend doing it in a child theme), or on the root file of your plugin.

function ts_add_security_headers() {
	// Are we on HTTPS, if not then do a redirect.
	if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
	        header("Status: 301 Moved Permanently");
        	header(sprintf(
            		'Location: https://%s%s',
            		$_SERVER['HTTP_HOST'],
            		$_SERVER['REQUEST_URI']
        	));
        	exit();
	}

	// Add all the security headers.
	header('X-Frame-Options: SAMEORIGIN');
	header('X-Content-Type-Options: nosniff');
	header('Referrer-Policy: strict-origin-when-cross-origin');
	header('Permissions-Policy: microphone=(),camera=()');
	header('Content-Security-Policy: "frame-ancestors \'self\'"');
	header('Strict-Transport-Security: max-age=31536000');
}
add_action('after_setup_theme', 'ts_add_security_headers', 1);

b. Adding HTTP headers in vanilla PHP

If you’re running your site on vanilla PHP, then you can extract the code in ts_add_security_headers() and run it as close to the top of your program as possible. This will achive a similar effect to the WordPress code.

3. Testing your HTTP headers

Once the headers are installed, you can test your site out at Security Headers. If they have been implemented properly, you should get an A+ grade on your site.

Do also test your site out manually. The security policies that I’ve offered as copypasta restrict access to your site in certain ways, so some things may break:

  1. If anyone has an <iframe>, <frame>, <embed> or <object> linking to your site, it will break.
  2. If any of your outbound links are dependent on referrer URLs, they will also break.
  3. If your site contains pages or features that use the microphone or camera of the user, they will break.
  4. If your site does not support HTTPS, the site will become inaccessible.

If you’d like to adjust the headers manually, you can refer to the table below for a brief explanation of what each of the headers control.

HeaderDescription
X-Frame-OptionsX-Frame-Options tells the browser whether you want to allow your site to be framed or not. By preventing a browser from framing your site you can defend against attacks like clickjacking.
X-Content-Type-OptionsX-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. The only valid value for this header is "X-Content-Type-Options: nosniff".
Referrer-PolicyReferrer Policy is a new header that allows a site to control how much URL information to send when navigating to another page, and it should be set by all sites.
Permissions-PolicyPermissions Policy is a new header that allows a site to control which device features and APIs can be used in the browser, and it can help restrict the damage it does to your users should your site be compromised. For example, if your website never uses the Camera, you can prevent your website(s) from accessing the Camera of your users’ devices by setting it on this policy.
Content-Security-PolicyContent Security Policy is an effective measure to protect your site from cross-site scripting (XSS) attacks. By whitelisting sources of approved content, you can prevent the browser from loading malicious assets should your site be compromised.
Strict-Transport-SecurityHTTP Strict Transport Security enforces the use of HTTPS on browsers when other users visit your site. While great, this will disallow users from accessing your site from HTTP, so you must make sure that your site always redirects to HTTPS and has a valid HTTPS certificate.
Copywriting adapted from SecurityHeaders.com

Leave a Reply

Your email address will not be published. Required fields are marked *

For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

I agree to these terms.