This blog post covers the four YouTube sessions in which Tanya Janca and I implemented Transport Layer Security (TLS) and security-related HTTP response headers (security headers) on our project website, https://devslop.co. I would like to summarize what we have implemented and why!
You can find the sessions on the OWASP DevSlop channel on YouTube.
Thanks to the very useful and informative blog by Troy Hunt, we have learned that not only should the transmission of sensitive information, such as credit card numbers or login data, be protected by TLS, but that every website should implement TLS.
Why? Because on open, and therefore untrusted, Wi-Fi connections (hotel, airport, etc.) traffic could be intercepted and harmful content such as scripts, malware and other bad things could be injected. This means that a user connecting to our website may not only load the content we provide, but also harmful content. We could potentially harm our visitors if we did not provide TLS! That’s not what we want. So, our journey to TLS started…
For a complete list of risks, read Troy Hunt’s blog for more info.
In our very first session (it was a training session), we explain why we want to add TLS to DevSlop.co: OWASP DevSlop Season 1 Episode 0 (S01E00).
Of course, everyone knows the free TLS certificates from Let’s Encrypt. Unfortunately, this was not an option for us, as DevSlop.co is implemented as a Microsoft Azure App Service and it is not yet compatible.
Luckily for us, because we are an open source project, DigiCert was generous enough to sponsor us with a free server certificate. Many thanks!
After proving that Tanya owns the site DevSlop.co, she generated a private key and a certificate signing request (csr). She sent the csr to DigiCert. In response, she got the public key, the server certificate.
Of course, we then wanted to know our Qualys SSL Labs rating (https://ssllabs.com). We got an A!
Also, try Hardenize. It gives you an overview of your web and email security.
Not only did we want to add TLS to our site, but we also wanted to add more security measures such as security-related HTTP response headers.
Scott Helme explains what we should implement and why. For further explanations, visit his blog.
The first two headers we added were the X-XSS-Protection and the Content-Type-Policy headers in OWASP DevSlop Season 1 Episode 1 (S01E01).
By adding the X-XSS-Protection response header with a value of 1, we tell the modern browser to enable the built-in XSS protection and to block an attack (mode=block).
X-XSS-Protection: 1; mode=block
In short, we define from which sources our site may load scripts, images, frames, fonts, etc. We control where the content on our site comes from.
Since we do not load content from another page, our CSP header is very easy to configure. We can be very strict and only allow content from our own site DevSlop.co, no subdomains allowed. And the block-all-mixed-content directive prevents loading any content over HTTP.
Content-Security-Policy: default-src ‘self’; block-all-mixed-content;
This header is a very effective control against XSS attacks and prevents harmful content from a malicious domain from being loaded.
How the CSP header is best configured depends very much on the application.
For example, adding the response header:
Content-Security-Policy: default-src ‘self’; img-src *.owasp.org; media-src *.owasp.org;
allows us to load images, videos and audio from *.owasp.org.
Very granular settings are possible. For more information, visit Scott Helme’s introduction to CSP.
After adding these two headers we have rating of a D on https://securityheaders.com. Of course that was not enough for us and we went on.
OWASP DevSlop S01E02 — Security Headers! shows the implementation of additional security headers.
We don’t want to allow our site to be framed in other pages because of an attack called clickjacking.
We forbid this in modern browsers by adding this header:
Possible settings are DENY and SAMEORIGIN. With SAMEORIGIN, we allow the site to be framed on our page.
This header tells the browser not to sniff the content-type, but to rely on the content-type provided by the application.
There is only one possible value:
This header disables the possibility of an incorrect and potentially malicious interpretation of the content.
Imagine someone visits our website and then connects to another site. The browser would send the request header Referer: https://devslop.co/link/to/site to the other site. We don’t want that much information being sent to the other site. Therefore, we add the following response header:
We instruct the browser to send the request header Referer: https://devslop.co only if the browser connects to https://othersite.com and to send a blank referrer when the browser connects to http://othersite.com. We prevent the information from being sent when the scheme is downgraded and we also truncate the path after DevSlop.co.
Many possible values can be set. For a complete list, read this blog post about the referrer policy.
After adding these three headers, we got an A on SecurityHeaders.com!
Since we are a security project and we want to learn more, we want to reach an A+ on both SSLLabs.com and SecurityHeaders.com.
For an A+ on SecurityHeaders.com, we need to implement Strict Transport Security. We will also add the Feature-Policy.
The HSTS header tells the browser to directly connect to https the next time the user calls DevSlop.co for a certain period of time, even if the user enters http instead of https.
We plan to configure HSTS to be set for one year. We don’t have any subdomains yet, but if we add subdomains, we also want to add HSTS there. Therefore, we add includeSubDomains. We will configure this by adding the following header:
Strict-Transport-Security: max-age=31536000; includeSubDomains
After adding this HSTS header, we will also get an A+ on SSLLabs.com.
This behaviour could become even more strict by hard coding https://devslop.co into the so-called preload list in modern browsers. We do not plan to implement that at the moment.
This is the newest security header. We tell the browser which modern browser features we want to allow for our website.
Feature-Policy: camera ‘none’; microphone ‘none’; speaker ‘self’; vibrate ‘none’; geolocation ‘none’; accelerometer ‘none’; ambient-light-sensor ‘none’; autoplay ‘none’; encrypted-media ‘none’; gyroscope ‘none’; magnetometer ‘none’; midi ‘none’; payment ‘none’; picture-in-picture ‘none’; usb ‘none’; vr ‘none’; fullscreen *
To explain only a few of the keywords: We forbid the features camera and microphone and only allow speaker for our own site. We also allow fullscreen.
For more information on this new header, see https://scotthelme.co.uk/a-new-security-header-feature-policy/
With these two headers added, we would get an A+ on SecurityHeaders.com and on SSLLabs.com. We plan to do that in the future.
We also plan to do add:
- Secure settings, additional flags for our cookies
- X-Permitted-Cross-Domain-Policies: none
- Expect-CT: (not currently supported by our provider)
Tanya and I are looking forward to seeing you again in one of the next shows!