Secure POST request with CSRF in NodeJs

Security is a major concern when you creating an app or website. Frameworks have built-in security features that sometimes you just need to activate. Anyway, We are not talking about the framework in this post. But when you build something from scratch then you must keep this in your mind.

Prevent Cross-Site Request Forgery

Cross-site request forgery, also known as one-click attack or session riding and abbreviated as CSRF or XSRF, is a type of malicious exploit of a website where unauthorized commands are transmitted from a user that the web application trusts

Wikipedia

Lets start with a simple FORM. First of all create a directory and setup express and body-parser into it.

mkdir csrf-demo-app
cd csrf-demo-app
npm init -y
npm install express body-parser --save

Now create a file index.js and start writing with the following code or just copy and paste.

const express = require('express');
const bodyParser = require('body-parser');

const PORT = process.env.PORT || 3000;
const app = express();


app.use(bodyParser.urlencoded({
	extended: true
}));


app.get("/", (req, res) => {
	res.send(`
		<h1>Hello, </h1>
	    <form action="/" method="POST">
	      <div>
		        <label for="name">Enter Your Name:</label><br/>
		        <input id="name" name="name" type="text" />
	      </div>
	      <input type="submit" value="Submit" />
	    </form>
	`);
});

app.post("/", (req, res) => {
	console.log(`Hello, ${req.body.name}`);
	res.send(req.body.name);
});


app.listen(PORT, () => {
	console.log(`Listening on http://localhost:${PORT} 👍`);
});

Now you just have to run your script with node index.js and open the displayed URL on your terminal. It is a simple FORM that asks about visitor name. A very simple example of GET and POST request.

Simple GET Request

Take a look on this Simple Form that do not have any security feature included. So anyone who knows this POST URL can directly submit the value through script.

Secure POST request with CSRF-Token

There are many modules that you can use to generate CSRF token. We are using csurf module along with cookie-parser.

npm install cookie-parser csurf --save

Now lets build middleware to protect POST, PUT, PATCH or DELETE requests. This middleware check the csrf token existence. Let’s implement the csurf and cookie-parser to our existing codes.

const express = require('express');
const bodyParser = require('body-parser');
const csurf = require('csurf');
const cookieParser = require('cookie-parser');


const PORT = process.env.PORT || 3000;
const app = express();


const csrfMiddleware = csurf({
	cookie: true
});


app.use(bodyParser.urlencoded({
	extended: true
}));
app.use(cookieParser());
app.use(csrfMiddleware);

Now every request is handled by our middleware except GET request. Middleware will check csrf-token on every POST, PUT, PATCH or DELETE request if csrf-token doen’t exists then middleware will block your request to proceed. Lets implement csrf-token to our GET request.

app.get("/", (req, res) => {
	res.send(`
		<h1>Hello, </h1>
	    <form action="/" method="POST">
	    	<input type="hidden" name="_csrf" value="${req.csrfToken()}" />
	      	<div>
		        <label for="name">Enter Your Name:</label><br/>
		        <input id="name" name="name" type="text" />
	      	</div>
	      	<input type="submit" value="Submit" />
	    </form>
	`);
});

app.post("/", (req, res) => {
	console.log(`Hello, ${req.body.name}`);
	res.send(req.body.name);
});

Take a close look on the GET request. As you noticed that we have implemented our CSRF token in the form.

<input type="hidden" name="_csrf" value="${req.csrfToken()}" />

That’s it, Now every request except GET is handled by our middleware. This is how you prevent CSRF attack to your server.

Posted by Jogesh Sharma

Jogesh Sharma is a web developer and blogger who loves all the things design and the technology, He love all the things having to do with PHP, WordPress, Joomla, Magento, Durpal, Codeigniter, jQuery, HTML5 etc. He is the author of this blog.