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
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
npm install cookie-parser csurf --save
Now
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.