Security from a web developer’s perspective
Security from a web developer’s perspective
Do you do any online banking? Have you ever noticed that little lock icon (usually green) in the address bar while using your online banking site? That is by far the most prominent security indicator that we’ve come to know. That little lock icon means your browser is connecting to the bank’s server using a protocol called SSL, or its lesser known replacement TLS. Now what if you view the response headers? Have any additional security precautions be taken? So many questions can be asked regarding security! But let’s back up and step through how a secure request actually works.
When you visit a website on the internet, your browser is talking to servers from around the world using a protocol called ‘HyperText Transfer Protocol’, or as you’ll hear it referred to, ‘HTTP’. HTTP is a fine protocol, but it was created with an absolute lack of security. If you’re sitting in a coffee shop on the free WiFi, anyone on that same WiFi network can actually see what websites you’re browsing, and even worse, what you’re submitting to those websites. If we think about this while visiting our online banking website, it would mean anyone on the same network could see your account credentials! This is called a man-in-the-middle attack. But not to worry, this problem has been solved by the addition of a new protocol called ‘HTTPS’ 1. Technically, it was supposed to mean ‘HyperText Transfer Protocol Secure’, but most people think about it as HTTP with the additional ‘S’ meaning SSL.
1 Man-in-the-middle attacks can still occur over HTTPS by spoofing certificates, or usually root CA’s. As a best practice, you should only check your online banking (or any other data sensitive sites) from a trusted computer and trusted network. At home is usually the best place, with your workplace being a close runner up.
HTTPS? SSL? TLS?
SSL stands for ‘Secure Sockets Layer’. This is a layer that is placed on top of HTTP which allows the content between your browser and the server to be encrypted, so only you and the server actually know what’s being sent and received. Now security is never this simple, and we have a lengthy list of vulnerabilities (with very, funny, names) that have lead us to deprecating SSL in favor of ‘Transport Layer Security’ or ‘TLS’ for short. TLS is very similar to SSL, but introduces a few new features, and fixes some of the shortcomings of SSL.
So now that we know about HTTPS, what else can we do to improve security? As developers, we have a few additional tricks we can use to protect users on our sites. Let’s take a look at some browser headers that we can and should utilize on all of our sites. Many programming languages and frameworks have packages that can help facility with these headers such as the one I wrote for Go.
Security-related response headers
Here is a list of additional headers that can and should be utilized. I’ve included some examples, but be sure to read the specifications and watch for implementation “gotchas”. If you are using Nginx, you can see the implementation examples here.
The Access-Control-Allow-Origin header is part of the cross-origin resource sharing (CORS) group. This specific header can be used to define a list of origins (websites) to access your site via across origins. The most common example would be an AJAX request.
Content-Security-Policy: default-src ‘self’
The Content Security Policy (CSP) header can be used to mitigate against certain attacks like Cross Site Scripting (XSS) and data injection attacks. It works by allowing you to define a list of origins that should be allowed by this website. This header is especially helpful on sites that allow user generated content.
PublicKey: pin-sha256=“base64+primary==”; pin-sha256=“base64+backup==”; max-age=5184000; includeSubdomains; report-uri=“https://www.example.com/hpkp-report”
The Public Key Pinning Extension for HTTP (HPKP) header is still in draft, but most major browser already support it. Key pinning allows you to specify your certificate’s fingerprint so that man-in-the-middle attacks can be detected and stopped.
Strict-Transport-Security: 315360000; includeSubdomains; preload
The Strict Transport Security (HSTS) header allows you to “mark” your website as HTTPS only for a certain period of time (usually a year). This also allows your browser to turn insecure links to your site into secure links. If your site can not be reached via HTTPS, an error message will be displayed and the user will not be able to access the site.
The X-Content-Type-Options header was created to protect against the MIME type confusion attack. Some browsers can take an educated guess as to what content type a file is, instead of trusting what the header ‘Content-Type’ says. This process can trick the browser into executing malicious code on the user’s browser.
The X-Frame-Options header was created to address Clickjacking attacks. Clickjacking is a technique where you embed one website in an iFrame and thus trick them into clicking something different than what the perceived.
X-XSS-Protection: 1; mode=block
The X-XSS-Protection header can be used to enable cross-site scripting (XSS) filters. Most modern browsers have the ability to identify and block cross-site scripts from executing, so this header just allows you to give the thumbs up or not.
Secure by default
As the web continues to march forward, it’s clear that a secure web will be dominant. Google has called for HTTPS everywhere and has even made HTTPS an SEO ranking signal for their search engine. Google is also suggesting the idea of changing the way browsers display secure vs non-secure websites. So instead of knowing a site is secure, they would flip that and mark sites the are not secure. While HTTPS may still be perceived as a premium service today, we are moving forward with several tools that will change the way we think about HTTPS and the secure web.