Application Security and Hardening
Geekwise Academy
Week 6 - Authorization Continued and Server Hardening
Instructors:
Corey Shuman
Slack Channel:
Github Repo:
https://github.com/coreyshuman/GeekwiseApplicationSecurity
Lecture Notes:
http://coreyshuman.github.io/GeekwiseApplicationSecurity/LectureNotes
Table of Contents:
This week we will continue to implement JWT authentication throughout our application.
Once a user has logged in and a JWT token has been created, it must be stored in the user's browser so that the token can be added to the header on each subsequent API request.
We could store the token in a variety of places. For this application, let's put it into Local Storage.
[Local Storage (Mozilla)](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)
Modern browsers have a `localStorage` property on the window object which gives us access to a storage object for the given domain's origin. We can set, get, and remove item's using the following methods:
[Request Object](https://developer.mozilla.org/en-US/docs/Web/API/Request/headers):
[AJAX](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader):
The application is currently wired up to work on a single server using cookies and form submits. We will work together to add a second mode of operation which will allow our application to work with JWT Tokens and an API server.
In this section, we will look at a variety of tools and settings we can use to harden our application against common vulnerabilities. We will use the [ExpressJS Best Practice Security](https://expressjs.com/en/advanced/best-practice-security.html) resource as a starting point.
When using ExpressJS, the "easy" solution is to install [Helmet](https://www.npmjs.com/package/helmet), which is a collection of smaller middleware functions designed to secure a web app. We will look at some of those smaller functions in detail today so that we understand the underlying vulnerabilities and their accompanying solutions.
[Reference](https://content-security-policy.com/)
[Browser Test](https://content-security-policy.com/browser-test/)
The `Content-Security-Policy` is a fairly new HTTP response header which allows us to reduce the risk of XSS on modern broswers by declaring what dynamic resources are allowed to load. The header value is made up of one or more directives separated with a semicolon `;`. The reference above provides a full list of all CSP directives. The following example is a good starting place for most apps:
This example allows images, scripts, AJAX, and CSS from the same origin, and does not allow any other resources to load.
The `X-Powered-By` header can allow hackers to target specific vulnerabilities of our server framework if we declare which server we are using in the header. Disabling this header provides us some [security through obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity). All we need in our code is the following:
As Internet speeds and caps are increasing, security is taking precedence over caching and efficiency. If you have old versions of HTML or Scripts cached on client machines, they could be left vulnerable long after you have fixed a bug. The following four headers are used to disable most browser caching:
This of course will negate the performace benefits of caching and may not be a good fit for all applications. As an alternative, bundled resources can be cached and versioned by changing the name of the file when a new version is released. This will inherently bust the cache and load the new file version.
More on that topic here: [Revving Filenames](http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/)
The `X-Frame-Options` header restricts which sites put your site into an iframe. For example, on my site (`http://coreyshuman.com`) I could include an iframe with `example.com`. The `X-Frame-Options` that `example.com` chooses will control whether the iframe is allowed or not.
`X-Frame-Options` has 3 options: `DENY`, `SAMEORIGIN`, and `ALLOW-FROM`. `DENY` will prevent your site from appearing in any iframes. `SAMEORIGIN` will allow your site to be included in frames from the same origin. `ALLOW-FROM` will let you pick specific domains that are allowed to include your site in an iframe.
To test this, try including an iframe with `src='google.com'` on your site. Google's `X-Frame-Options` is set to `SAMEORIGIN`, so the iframe will refuse to load.
[Mozilla X-XSS-Protection Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection)
The `X-XSS-Protection` header stops pages from loading when they detect a reflected coss-site scripting (XSS) attack. This was initially a feature of Internet Explorer, but Chrome and Safari have adopted the header.
This feature has mostly been replaced by using strong Content-Security-Policy settings, but is still used commonly to protect older browsers that don't yet support CSP.
Consider signing or encrypting cookies to ensure they are not tampered with. In our app, we use `cookie-session` to sign our session cookie. Additionally, avoid using the default session cookie name as this can open our app to target attacks. Instead use generic cookie names. For example:
As an aside, explanation of the `trust proxy` setting can be found here: [ExpressJS Behind Proxies](https://expressjs.com/en/guide/behind-proxies.html)
Set the following cookie options to enhance security:
We will each build a simple test page to demonstrate a feature of CSP. Each person will work on a different protection component in CSP. For example, `script-src`, `img-src`, or `style-src`. The goal is to build an injection based around your specific component, then show how CSP rules can prevent the vulnerability from running. Use the [CSP Browser Test](https://content-security-policy.com/browser-test/) for inspiration.