http security headers

There is a new breed of HTTP response headers, the sole purpose of which is to improve the security of your site for your readers.

In the following post, I’m going to describe the most popular headers, what they do, and why you should use them.

Content-Security-Policy: connect-src 'none' ;
    font-src 'self' ;
    form-action 'none' ;
    frame-ancestors 'none' ;
    child-src ;
    img-src 'self' data: ;
    media-src 'none' ;
    object-src 'none' ;
    script-src 'self'
        'unsafe-inline' ;
    style-src 'self' ;
    default-src 'none'
Strict-Transport-Security: max-age=31531337; includeSubDomains; preload
Upgrade-Insecure-Requests: 1
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1 ; mode=block
Public-Key-Pins: pin-sha256="abcabcabcabcabcabcabcabcabcabcabc=="; max-age=31531337 ; includeSubdomains;

Content-Security-Policy (CSP)

This header tells the browser where it is allowed to fetch extra content from. It basically helps thwart code injection attacks that would normally fetch and run code from a remote site hosting malicious code.
This injected code could be unwittingly served from your website, or could be injected in mid-air MITM style.

Strict-Transport-Security (HSTS)

This header should ONLY be included in your headers when served over HTTPS, otherwise it is a breach of the specification. This is pretty much because this header is saying “Always Use HTTPS” and to put it in the HTTP header enables a MITM attack to remove the header entirely, which provides you as a site owner with a false sense of security that you’ve used the header in the first place.

You should be upgrading all HTTP requests to HTTPS and setting this header on all subsequent HTTPS responses – this way any browser that re-connects to your site won’t attempt to connect using HTTP, it will remember to only use HTTPS. This is helpful for when you have an old site with lots of links around the place referring to your site using the HTTP protocol.


This header is somewhat redundant with site-wide usage of HSTS, but if portions of your site are still HTTP and are being migrated to HTTPS, this is the header you should use in your HTTP (not HTTPS) responses to tell the browser that all links in the content being served should be treated as if they were `https://` instead of `http://`.


The only value for this header is `nosniff`. It basically prevents the browser from trying to guess the content type of a fetched resource.
This adds a useful stop-gap in the event that one of the resources being referenced from your site changes from something benign to something malicious – if an image hosted on your server is replaced somehow with malicious JavaScript, but the header type being returned along with the javascript is still `Content-Type: image/png` or similar, then the browser should try to interpret that JavaScript as an image, and if it fails, then ignore it, raise an error, and move on.

Historically, where the Content-Type of data returned from a request doesn’t match what the browser is expecting, the browser takes it upon itself to try to guess the content type to use the content anyway, which lead to security issues.


Prevent your site from being served from within someone else’s `iframe`. This has been a popular way for hackers and clickjackers to make you think you are browsing one site, but instead you are just browsing the site through an invisible frame in a different site. This enables mouse or keyboard actions on the iframe (making it look like you’re clicking on your site) to be hijacked and/or recorded.

The `SAMEORIGIN` policy as used above, ensures any iframes linking to [parts of] your site are themselves hosted on the same domain as your site itself. So you can have parts of your own site in your own iframes, but no other domains are allowed to host an iframe pointing to [parts of] your site.


This header is largely redundant, in that XSS protection should be enabled by default in all browsers anyway, but this serves to forcefully turn it on if it isn’t already.

Cross-Site Scripting can happen in several ways, but generally involves scripts executed on a different site to send requests from that site to your site, but to make it look like the user is doing it deliberately. A common scenario is that a request launched via JavaScript from `` makes a `POST` request to your site, e.g. to perform some action that only that user can perform, such as update their password… Or transfer money from their bank account…

Public-Key-Pins (PKP)

This is a way of “pinning” the SSL certificate your site is using to your domain, so if a server tries to impersonate your site, the SSL connection will be rejected, as they won’t have the site certificate they need.

These days there are a lot more CAs than there ever used to be, and recently there have been some emerging that offer free SSL certificates – like Let’s Encrypt for example.
(Incidentally, I wholly recommend this site and will be switching my site over to using it very soon.)

In the event that the domain is DNS hijacked, your browser may try to make an SSL connection to a new server… if this happens for a long enough time period, an SSL certificate could be systematically issued to this new server, so when you connect to this new server, you’d see the pleasing green address bar (assuming their very new certificate is valid), and the domain name matches what you originally typed in.
At this point, before you’ve even typed anything in, your browser has sent this malicious site your protected session cookies, and possibly even entered your username and password into the login dialog on your behalf, if you’ve got a password manager that does this for you.

Your browser doesn’t know not to do this! It’s a legitimate site that you’ve logged into before, it’s just got a different SSL certificate, but who cares, right? As long as it’s valid?!…..

Public Key Pinning means that when you connect to a legitimate site with SSL, the browser will remember the signature of that certificate until it expires (with some extra conditions to enable the certificate to be updated).

So when a MITM attack does happen and your browser tries to connect to this new IP with HTTPS, it will be automatically rejected and you should receive a nice big red warning page telling you the site certificate is not what it expected.
This thwarts an attack that is getting progressively easier and cheaper to carry out.

*   *   *

At last count there were 176 Root CAs in the list bundled within Mozilla Firefox.

These authorities are trusted implicitly – any valid certificate signed by one of these is trusted by your browser, at least unless it violates the PKP header.

These CAs sign certificates for “Intermediate Certificate Authorities” who in turn can sign certificates for other intermediate CAs, as well as the usual end-user domains.

This all means that there is a whole heap of delegated trust out there, just one of those CAs or intermediate CAs needs to be compromised in order to allow the hacker to sign certificates for any domain they like, and carry out highly successful MITM attacks without detection.

/! If you install your own root CA certificate into your system, you’d better make sure that the private key for that certificate is kept somewhere *really really safe* – because if anyone else gets hold of it, they can perform a MITM attack against you on any site and you probably won’t notice.

Companies unfortunately use internal root CA certificates quite a bit, primarily so that they can easily manage secure connections within the company intranet, but it also enables them to intercept all your other SSL connection setup requests at the gateway, and effectively perform a MITM attack against you at your work’s gateway, albeit with less malicious intentions… (you hope.) So do you trust your company to handle this certificate responsibly? If it gets into the wrong hands, a person with malicious intentions could intercept and read all of your communications made on the company network.

All of them. (Except the ones protected with PKP!)

This is why it’s a big deal when owners of root CA certificates misbehave – the consequences could be catastrophic.

Similarly, when CAs are compromised – it will undoubtedly end badly for the company responsible, or they will at least have the wrath of governments to deal with. These incidents undermine the security that is fundamental to the Internet.

According to Scott Helme’s research, only 0.0265% of sites in the top 1 million sites on the web (according to Alexa rankings) were using PKP. This is a little concerning, given what we’ve just learned – and although this number has increased by ~68% in 6 months, it’s still a tiny number. Companies aren’t doing enough, but maybe

I leave the choice up to you which security headers you use on your site. I suggest you use them all.

WordPress Plugin

I have written a WordPress plugin that enables the owner to add their own custom HTTP response headers to their WordPress site. I wrote it because I couldn’t find any existing plugin that enabled me to do this, at least not with the flexibility I wanted.
This is the method I used to add (nearly) all of the security headers described in this blog, to my site.

Check it out here: Headit.

Further Reading

my password generator

Passwords are everywhere, we use them for logging into all sorts of services, and typically we use a very small number of passwords, sometimes with small variations. In this article I explain why and how you should be using a password generator.

are my passwords strong?

Using similar passwords everywhere is bad practise – it means if an attacker gets a password for one service you use, they will likely be able to gain access to your other accounts elsewhere.

The reason you don’t use lots of different passwords is because it’s difficult for us humans to remember them all, especially when we’re told to use special characters, numbers, and mixed case letters, and avoid using words, patterns, or repetition.

Because this is what goes into making an OK password, but there is a better way.

so what is a strong password?

To create a strong password the only real option is to use a secure password generator. These use a cryptographically-secure random number generator to create the strongest passwords possible with the available limitations, such as length, characters available, etc.

What secure passwords look like:
64 character alphanumeric password:
64 character alphanumeric password with symbols:

So you get the idea. Even short passwords (16 characters or less) are much more secure than any password you can actually think of, even mashing your face on the keyboard will result in reproducible patterns. If an attacker mashes their own face into a keyboard for hours and hours, not only is this hilarious for everyone watching, but chances are that they will have generated several passwords that are similar to yours. They can then add these “mashed face” passwords to a database to use in the future, to save themselves the face-pain if nothing else. (This is what password databases are for – they contain billions of passwords to use in cracking systems. I’m not covering rainbow-tables here, but please feel free to read up on it in your spare time.)

why are my normal passwords not strong?

Basically it comes down to the ease at which they can be computationally guessed, given whether the attacker has a hash, hint, or other personal data that you may have used to create your password, such as patterns you’ve used to create passwords on other sites.

If an attacker has one of your passwords, are your other passwords sufficiently different to prevent the attacker guessing the other ones?

If you use `las4nco7h3jpjse;facebook` as your facebook password, what combinations do you think the attacker might try to use to access your gmail account?
Perhaps `las4nco7h3jpjse;gmail` and `las4nco7h3jpjse;google` would be their first two attempts?

It only takes one of your accounts’ passwords to be compromised using this pattern for all of your other account passwords to become guessable.

how do i generate a strong random password?

I use a password generator that I wrote myself, which is clean and simple. It is based on principles of generating numbers with high entropy using a secure random number generator function built into Javascript, and available on most (if not all) browsers.
This extension works on Chrome and Firefox at the time of writing, and it doesn’t work in Internet Explorer.
(I would appreciate it if people would tell me via comments if it works in other obscure browsers.)

Drag the following button into your bookmarks bar to use this password generator, the code is also shown a bit further down the page.

Password Generator

Clicking on it in your toolbar should result in a window like this:

password generator

Click the buttons to generate passwords according to the length and complexity required.

but how am i supposed to remember all these passwords?

You aren’t.

There are several browser extensions and third-party applications that enable the secure storage of passwords, such as KeyPass, Keeper, and even as a core part of the Google Chrome browser.

Many of these secure password stores are available as extensions to your existing Firefox, Chrome or IE browsers, and on mobile devices, so you can generate and submit a new password on one device, and it will be available on your other devices automatically.

but what if someone gets my password manager password?

Using a password manager does mean you typically need to remember at least one relatively secure master password, but these services do typically offer two-factor authentication, which forces anyone who attempts to log in to your password storage to also have access to your phone or mobile device, so it can send you a text message to confirm the person who owns the password storage is also in control of the registered phone number for the account.

Google, Facebook, Twitter and others support two-factor authentication, and you should be using it whenever possible.

the geeky bit

The bookmarklet is a block of Javascript code that executes on the current page you are browsing, but doesn’t send any data to any server at all. This means the password generated only ever exists in the browser window. You have the option in the tool to generate various password sizes, with or without special characters. It is also relatively easy to change the code if you want additional buttons.

From a security perspective there are a couple of other features this password generator makes use of:

  1. By default it obscures most of the password from view, so if your screen is being watched (either by shoulder-surfing or by a more nefarious screen watching software utility) then the password is still moderately protected. There is a ‘show password’ button so you can check the password looks as you might expect, but this defeats the security feature.
  2. If you have a keylogger installed on the computer, the copy-paste action of the password text is not likely to be captured by the keylogger, which it would be if you had to type it in manually. Copy-pasting passwords also reduces the likelihood that you will get the password wrong, and makes you feel more comfortable using absurd-looking long passwords with lots of special characters.
  3. The bookmarklet relies on no third party code, so there are no connections made to any other resource to generate or store your password, or to facilitate any component of this utility.

Here’s the code for the password generator with a bit of wrapping and white-space to make it more readable.

javascript:(function() {
    var x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
            var bb = d[C]('button');
                var f=new Uint8Array(ct),
    B[a](d[ctn]('password hidden for security - click to show'));
    m(ctn,'Press Ctrl-C to copy your new password ');
    m(ctn,' a-zA-Z0-9');
    m(ctn,' with symbols');

The code is minified somewhat, as URLs are limited to 4096 bytes – this code is way below that anyway, but it makes it look more exciting if nothing else.

what is the difference between random and secure-random?

I’m glad you asked.

Generating random numbers with normal ‘random’ functions aren’t considered secure because although the output of these functions appears random, and the randomness usually stands up to basic statistical analysis, standard random number generators are only random enough to be used for non-security related scenarios. Normal random number generators should only be used where the numbers generated aren’t predictable or reproducible.

The last few digits of the current system time in microseconds might be used as a simple generator, but these numbers are selected at intervals from the same source, with little external influence, so reproducing or predicting the next number in the series would be a lot easier than if the numbers were produced by a more secure system. So `current microseconds mod 6` is great for generating dice rolls, but not so great for generating passwords.

To generate random numbers in Javascript that are strong, we use `window.crypto.getRandomValues()`. This is a built-in security component of modern web browsers. If we just need a normal ‘random’ number, we use `Math.random()` instead, which is quicker, but not secure.

further reading

linux tips: screen

When you’re working in a remote terminal environment, being able to resume a session can be an invaluable tool – especially when the connection isn’t stable.

When connecting to a UNIX-based environment (like the many varieties of Linux, or OSX) there is a handy utility called `screen` that effectively allows you to run tabbed terminal consoles within a single terminal console. This has many benefits, not just the ability to resume the connection if the connection drops.

adding a status bar

The first thing to do when starting any new screen session, is to add a config file. This file changes the default look and feel of screen, which isn’t very intuitive if you’re just learning how to use it.
I’m going to use `vim` to write my config file, and I’m going to use a configuration that I pilfered from somewhere on the internet a while ago:

# ~/.screenrc
termcapinfo xterm* [email protected]:[email protected]
startup_message off
vbell off
autodetach on
altscreen on
shelltitle "$ |bash"
defscrollback 100000
defutf8 on
nonblock on
msgwait 0
hardstatus alwayslastline "%{b kw}%H %{r}%1` %{w}| %{y}%Y-%m-%d %c %{w}| %{g}%l %{w}| %{-b kw}%u %-Lw%{= rW}%50> %n%f %t %{-}%+Lw%
# (This fixes the "Aborted because of window size change" konsole symptoms found
#  in bug #134198)
termcapinfo xterm* 'is=E[rE[mE[2JE[HE[?7hE[?1;4;6l'
# (you may have to change the 'xterm' value to match your $TERM value)

The most useful lines in this config file are the last two – they add the status bar to the screen window, which contains the list of open terminal tabs – which is verrry useful and I don’t know why this isn’t the default setup.
In the configuration shown above, the status bar contains the hostname on the left, the system load on the near right, and the server date and time on the far right, and your list of open terminal tabs in the middle.
Save this file into your home directory (usually `/home/yourusername/.screenrc`) and start start screen by running the command `screen`, and your window should look similar to this:


tab navigation

Press `ctrl-a c` to open a new tab
Press `ctrl-a shift-a`, change the name, and press `return` to save.
Press `ctrl-a-a` to switch between your most recent 2 tabs, or use `ctrl-a [num]` to switch to the tab numbered `[num]`, i.e. `ctrl-a 1` to switch to tab 1, `ctrl-a 2` for tab 2, etc.

detach and re-attach

I’ve pointed out that I believe the most useful feature of screen is the ability to detach and re-attach to screen sessions in the event of being disconnected from the server – so how do you go about actually doing that?
When you have connected to the server, to create a new screen session you type `screen` – but to re-attach to an existing disconnected screen session, type `screen -R`.
Sometimes, if you have disconnected very recently, the old screen session might still be attached to your old session! In order to tell screen you want to resume an existing screen session, and forecfully disconnect it from any connected session, use `screen -dR`. This does mean that if you have superuser privileges on the system to which you are connecting, anyone else who can assume control of your account can also take control of your screen session!

To detach your current screen session, press `ctrl-a d`.

locking your screen session

While in a screen session, press `ctrl-a x` to lock your session. This protects your open terminal sessions from being taken over by someone who might have access to your account. This won’t protect you from much, but it does add an extra layer of security that can help to delay or prevent security breaches.

This becomes a more useful feature when you realise that as a superuser, you can have multiple terminals open in screen, each one connected to a different server, each one potentially logged in as a more privileged user than the original screen session itself – so if a hacker manages to acquire the user’s username and password, they would be able to log in and resume all of these already logged in sessions with little more than a single command.

… so Lock Your Terminal!

scrolling history

When in cursor mode, you can search for patterns, and highlight and copy text too.

  • Press `ctrl-a Esc` to enter interactive cursor mode
  • Use the cursor keys (`up`, `down`, `left`, `right`, `PgUp`, `PgDn`) to navigate back in the history of the current screen terminal
  • Press `Esc` at any time to exit cursor mode and return to normal interactive mode
  • Press `Return` to start highlighting text at the position of the cursor
  • Use the cursor keys to select desired text
  • Press `Return` again to copy the selected text into the screen paste buffer – This will also exit cursor mode and return to interactive mode
  • To paste the text you’ve just copied, press `ctrl-a ]` when you’re in a suitable location. You can use this technique to copy and paste chunks of text or commands between console windows in the same screen session.

When in cursor mode, you can also search forwards and backwards using `/` and `?` respectively, just like in `vim` – to search “up” the screen from the cursor location, enter `?`, type your search string, and press `return`.
To find the next or the previous piece of text that matches your entered search, press `/` or `?` again and just press `return`.

further help

To access the help menu in screen, press `ctrl-a ?` and you will be presented with a list of further commands you can try out, which aren’t described quite as concisely as they are on this page, but they are a useful cheat-sheet, once you learn how to read the syntax.


bonus content

You might have noticed that my terminal prompt has also been customised – the code for this is added to the end of the file found in `/home/[yourusername]/.bashrc` – add the following code to the end of your `.bashrc` file:

# ~/.bashrc
PS1="$(if [[ ${EUID} == 0 ]]; then echo '[33[01;31m]h'; else echo '[33[01;32m][email protected]'; fi)[33[01;34m] w $([[ $? != 0 ]] && echo "[33[01;31m]:([33[01;34m] ")\$[33[00m] "