ExpressJS Series: Applying standard security to ExpressJS Server
In the previous post, we used body-parser library to understand the request and parse the request body. We worked with library internals of working with parsing. I intend to touch real life use cases later, once we understand ExpressJS Framework better.
In this post, we will focus on applying Content Security Policy, Cross Site Scripting, Cross Site Request Forgery, and Rate limit safe guards. All this will be done in a very simple manner with just few libraries and few code lines additions.
If you are overwhelmed by the incomplete details above and what we are trying to achieve, have a quick look at the security best practices brief in the ExpressJS documentation before starting.
- CSP, CORS: Have you ever wondered what would happen if your site was open to requests from everyone and people start hacking attacks?
- Sanitization, CSRF, XSS: What if someone fills a form or comment and enters a (creepy) javascript snippet in a post of forum hosted on your site which gets displayed/loaded (because your did not sanitise for safety of HTML before rendering it in the forum post or comment)?
- Sanitization, XSS, CSRF: What happens if that creepy javascript posted in a unsanitized (uncleaned) document rendering starts capturing security tokens off cookies, taking off localstorage data, or just starts putting unending popping messages from that external script?
- Sanitization, XSS, CSRF: What if, that creepy javascript posted in a unsanitized (uncleaned) document rendering loads a heavy unnecessary javascript files, image, file, or infected file from a third party location?
- Sanitization, CSRF: What if, they save your site’s form and start sending form submits from local system? What if, this process gets automated by the hacker?
- Secure Protocol: What if, the hacker intercepted your client’s insecure requests during login or form submits or browsing in general?
- CORS, Rate Limiting, DDOS: What if, just to be noticed after hacking failure, they start annoying your server with huge amount of requests your server is not able to handle?
- CORS, Rate Limiting, DDOS: What if, they keep a automated agent or spider that makes constant 1Million or X requests every hour consistently for next one month or perennially? More, if your server is able to handle those requests, wont your cloud billing or resources get blocked or wasted?
- CORS, Rate Limiting, DDOS, CSRF, Targeted Vulnerability Attacks: What if, such requests are brute force (and automated request randomizer) attacks targeted at a very important section of the application because the hacker knows the vulnerabilities of the server or the application’s functioning (development vulnerability)?
There are more that we have not spoken about. The hacker never has the best interest and intentions for you. A protector safeguards by risk mitigation, not by teaching a lesson through cyber crimes. As an developer or an infrastructure or an security professional, you owe a lot of accountability, responsibility, and risk mitigation to your users and organisation to safeguarding their assets from hacks; and incase things go wrong then your response to it.
These packages address the risk mitigation part of security. They help you set up a bare basic standard protection against known vulnerabilities (in the least tedious manner).
Note that all these packages are ExpressJS middlewares. You can either apply them to all routes or a single route/group of routes based on need and security strictness.
HELMET
Helmet is a middleware that clubs many libraries together to give a comprehensive support against a few common attacks/known vulnerabilities. It may not cover all the use cases but it is one of the best packages I have seen that implements protection against these issues. With just few lines, it gives you a set of default security implemented for your server. This makes the ExpressJS server more secure out of the box.
Let use install it in our project:
npm install helmet -S
Let us add helmet() as a middleware. Look at the code in Line3 and Line 8:
It adds default security using libraries below (read more here) by default:
contentSecurityPolicy for setting Content Security Policy (CSP)
expectCt for handling Certificate Transparency
dnsPrefetchControl controls browser DNS prefetching ✓
frameguard to prevent clickjacking ✓
hidePoweredBy to remove the X-Powered-By header ✓
hpkp for HTTP Public Key Pinning
hsts for HTTP Strict Transport Security ✓
ieNoOpen sets X-Download-Options for IE8+ ✓
noCache to disable client-side caching
noSniff to keep clients from sniffing the MIME type ✓
referrerPolicy to hide the Referer header
xssFilter adds some small XSS protections ✓
I recommend you to add Content Security Policy (CSP) for your contents in your application by means of configurations like the code below (change based on your needs). The below code can be quite a standard but might need tweaks based on your requirement.
npm install helmet-csp -S
Change code like in lines below:
Lines 4, 12–26, 46–53
Whenever there is a violation, it will report to /report-violation using HTTP request by modern browsers. Read more about CSP in the Helmet CSP documentation here.
CORS
Let us implement Cross Origin Resource Sharing support using CORS npm package:
npm install cors -S
Add the support as in lines 30–36 below:
You can also use a logic instead of the origin option to enable whitelist identification for domains or IPs like below (taken from ExpressJS documentation and replacing line 31–34 above):
More, this whitelist may be a dynamic one coming from a database rather than just hard coded. The above is just an example of how it works.
CROSS SITE REQUEST FORGERY (CSURF)
If you have a lot of forms in your site or application, it will be wise to set up not just a captcha but also CSRF protection. You do not want forms being submitted from a external site or from a local machine when you are not expecting any (for security or resource utilisation purposes).
You can do that with csurf package. The package allows you to create a token using req.csrfToken() method; and then validating the token when a form request is made from the client. The documentation for the module resides here. I will not be implementing the csurf module now but will do that when we work on forms and use this package along with multer module.
EXPRESS RATE LIMIT
I definitely dont want DDOS — huge number of persistent attacks on my system. I dont wish my server to get choked, crashed, or be hacked by a randomizer. Let us install the express-rate-limit package using the command below:
npm install -S express-rate-limit
Changed lines 6, 39–47
Our ExpressJS Server implementation now has a simple standard security configuration implementation for:
Cross Origin Resource Sharing (CORS), Content Security Policies (CSP), Cross Site Scripting (XSS), Rate Limiting, No sniff for MIME Sniffing, Click jacking (frameguard), Hiding the Application Server for targeted attacks (X-Powered-By), Upgrading HTTP requests to HTTPS.
We will build on this. But for now, it is definitely a basic safeguard. These configurations and implementations do not guarantee “no hack attacks” from culprits but ensures you are ready atleast with the basic safeguards.
Note: Two other important aspects to ensure safety of your servers are
- strong server/infrastructure access plus logging policy (for risk mitigation, and post risk occurrence postmortems/response), and
- organisational data security policy for associated or non-associated actors to avoid human errors.
The last one is the cause of majority of cyber crimes.
A lot of concepts are associated with this post; and it is sanely not possible to cover all in a single post. Once we understand how to serve files and send a response from our ExpressJS server in the next posts, we will start touching these one by one; possibly each might require multiple posts. Do leave comments if you have a specific need/information to be covered.
In the next post we will understand how to serve a response (files, json, xml, etc) from the application/server.
What I need to know about serving a response: https://medium.com/@ganeshsurfs/expressjs-series-what-i-need-to-know-about-serving-a-response-b8964a0ff13
ExpressJS Series All Blogs: https://medium.com/@ganeshsurfs/expressjs-series-links-9e038be8d78b
Let me know how I did, and if you learnt something new. Do leave your comments, and dont forget to like the article.