Security is of paramount concern for all developers, and especially for developers using unopinionated web frameworks, like Express.
Since Express doesn’t have opinions about the correct way to create applications, it also does not have opinions about the correct way to secure applications. Securing the application, then, is a task left solely to the developer.
Luckily, it isn’t absurdly difficult to secure an Express application from common vulnerabilities on the web.
This article will focus on preventing CSRF, which stands for cross-site request forgery.
CSRF Explained
A cross-site request forgery occurs when a user who is authenticated on a site is forced to make an unwanted request to that site. This request originates from a different origin, and that’s what makes this is a cross-origin request forgery.
Take for example, a banking application. A user is authenticated on the banking website through cookie(s) in their browser.
What is a CSRF Token?
A CSRF Token is a piece of data that is random, unique, and attached to a form. Often, this data is included in a hidden input
tag with the data stored in its value
attribute.
Here’s a simple example of what a CSRF Token looks like in the wild:
<form method='POST' action='/'>
<input type="hidden" name="csrf_token" value="jdljlj3jg84cmfjaldfalJFD#feaDKDKDKDKD==" />
<label for="username">Username</label>
<input type="text" name="username" />
<button type="submit"/>
</form>
The first input
with the name
‘csrf_token’ is the actual CSRF token.
In order to function properly, the CSRF token must be generated by the server and then rendered on the page where the form
is held. Then, all requests from that page will have the input
with the csrf_token
name included in the request, and all requests which are made cross-site will not have it.
The reason why cross-site requests do not contain the CSRF token is that the server must render the actual page where the form
is held in order to attach the CSRF token to the form
which makes the desired request.
When a request is made to the relevant route, the CSRF token in the form must be matched against the CSRF token stored by the server. If the CSRF token is not present or does not match the CSRF token persisted on the server for that user’s session, the request cannot be completed.
Enough with the theory; it’s time to actually implement this in Express.
One can download the project for this article at this GitHub link, or they can generate an Express application like so:
The following is an example of how to order your routes so that certain endpoints do not check for a valid CSRF token.
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// create api router
var api = createApiRouter()
// mount api before csrf is appended to the app stack
app.use('/api', api)
// now add csrf and other middlewares, after the "/api" was mounted
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))
app.get('/form', function (req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', function (req, res) {
res.send('csrf was required to get here')
})
function createApiRouter () {
var router = new express.Router()
router.post('/getProfile', function (req, res) {
res.send('no csrf to get here')
})
return router
}
Reference Link – https://levelup.gitconnected.com/how-to-implement-csrf-tokens-in-express-f867c9e95af0 , https://expressjs.com/en/resources/middleware/csurf.html , https://www.npmjs.com/package/csurf