To strengthen security for web applications, HTTP response headers can be applied. They effectively provide the browser with a set of rules regarding how it can interact with the website,

I use the following iRule to apply these headers to virtual servers hosting web applications in F5 LTM. By adding the conditional statement, we are only adding the header if it doesn't already exist. That means by default our headers are optimal, but if for example, you need to allow a specific site to be framed, you can enable it on the web server, and the F5 will leave that header in place.

I'm also removing some common headers that leak server information. Not critical, but it all adds up to something resembling best practise.

iRule

when HTTP_RESPONSE {
    # Conditional headers as some 3rd party apps already have headers configured, i.e. Accellion.
    if {!([ HTTP::header exists "X-XSS-Protection" ])} { 
        HTTP::header insert "X-XSS-Protection" "1; mode=block"
    }
    if {!([ HTTP::header exists "X-Content-Type-Options" ])} { 
        HTTP::header insert "X-Content-Type-Options" "nosniff"
    }
    if {!([ HTTP::header exists "Strict-Transport-Security" ])} { 
        HTTP::header insert "Strict-Transport-Security" "max-age=16070400" 
    }
    if {!([ HTTP::header exists "X-Frame-Options" ])} { 
        HTTP::header insert "X-Frame-Options" "SAMEORIGIN"
    }
    if {!([ HTTP::header exists "Referrer-Policy" ])} { 
        HTTP::header insert "Referrer-Policy" "strict-origin-when-cross-origin"    
    }

    # Remove headers that leak server information
    HTTP::header remove "Server"
    HTTP::header remove "X-Powered-By"
    HTTP::header remove "X-AspNet-Version"
    HTTP::header remove "X-AspNetMvc-Version"
}

Header Descriptions

Strict-Transport-Security

Also known as HSTS. Forces a browser to connect to a site using HTTPS. The first time (unless HSTS Preload is configured) a browser connects it can use HTTP, after which the browser will redirect any HTTP attempts itself. Typically a server-side redirect will be a 301 or 302. In the browser developer tools, you can confirm the browser is executing HSTS by observing a 307 (internal) redirect.

Option Description
max-age Defines the timeframe browsers must redirect the website to HTTPS. The unit is seconds, and the minimum allowed is 6 months (15768000), but longer is recommended.
includeSubDomains Tells the browser that all subdomains of the current origin should be included. i.e. if HSTS is configured for www.musingitoutloud.com, use it for pihole.musingitoutloud.com also.
preload Preload is a way of proactively informing browsers to use HSTS, even if they have not been to the site before. This removes any possibility of an initial HTTP connection. Recommend checking out this site for more information.
X-Frame-Options

Defines what, if any, site is allowed to place the web app in an iFrame. This option has been superceded by the Content Security Policy's frame-ancestors directive, but still works.

Option Description
DENY Do not allow any website to frame this page.
SAMEORIGIN Only allow framing from pages of the same origin.
ALLOW-FROM: uri Specify specific pages which can frame the page.
X-XSS-Protection

This header stops pages from loading reflected cross-site scripting attacks when detected, in Chrome and IE. Largely unnecessary if a strong Content Security Policy is in place, however in the absence of a CSP I always add it.

X-Content-Type-Options

This header tells browsers not to load scripts and stylesheets unless the server uses the correct MIME type. Without this header, it is possible for browsers to incorrectly detect files and scripts of stylesheets which can lead to an XSS attack.

Referrer-Policy

This header improves security by ensuring websites don't leak internal URLs via the referrer header. Below is a subset of the available options. I wouldn't use any of those that I have omitted.

Option Description
no-referrer Never send the referrer header.
same-origin Only send the referrer on requests to the same origin.
strict-origin Send the referrer to all origins, but only the hostname. Remove the URI.
strict-origin-when-cross-origin Send the full referrer to same origin requests, but omit the URI when the requests are from a foreign origin.
Content-Security-Policy

Tricky to set up, but provides excellent security. I'm not currently using it, and there are plenty of resources from more comprehensive that I can put together.

https://scotthelme.co.uk/content-security-policy-an-introduction/
https://scotthelme.co.uk/csp-cheat-sheet/
https://infosec.mozilla.org/guidelines/web_security#content-security-policy
https://www.owasp.org/index.php/Content_Security_Policy


Resources

Scott Helme's far more comprehensive look at hardening security headers, including instructions for adding them to web servers Nginx, Apache and IIS.

https://securityheaders.com/ to scan your site for header configuration.

https://observatory.mozilla.org/ will scan your site for a range of security issues, including response headers. It also includes some 3rd party scans, including Security Headers.

Web security best practise information from Mozilla.