Monday, March 08, 2021

Mitigate ExpressJS CSRF using csurf npm module tutorial

Cross-Site Request Forgery attack is a prominent and classic web-based attack where you can request sensitive actions on behalf of the users and that may cause severe damage to the user data. To overcome such request forgery issues, a CSRF token is added explicitly to the request header or in the cookie or post request body which is then decoded on the server-side and validated against the session.

Mitigate ExpressJS CSRF using csurf npm module tutorial
Mitigate ExpressJS CSRF using csurf npm module tutorial

Install

> npm install csurf

Initialize

We've imported csrf module and initialized the csurf module with a cookie as a false option by default. This would start accepting the Anti-CSRF tokens either via header or request body which effectively prevents csrf attacks instead of sending cookies.

var csurf = require('csurf')

var csrfProtection = csrf({ cookie: false })

CSRF Token Generation

As the client-side API requires attaching the ant-csrf token, We need to send out the csrf token by generating it and responding via GET API. Either one can respond with render function or directly with JSON/XML based response to the frontend client.

app.get('/form', function (req, res) {
  // pass the csrfToken to the view
  res.render('send', { csrfToken: req.csrfToken() })
})

CSRF Validation Middleware

As the validation of the CSRF token happens in the server, ensure to install body-parser to parse any tokens passed via body part or access the token directly via header. Add the middleware above all request routes to have seamless verification of the token before executing the actual route.

app.use(csrfProtection)

Error Handling

To efficiently respond to the API client or frontend service, I would strongly recommend adding an error handling layer before the request route with a specific format response by which clients can easily parse and understand the error message thrown from the server.

app.use(function (err, req, res, next) {
  if (err.code !== 'EBADCSRFTOKEN') return next(err)
 
  // handle CSRF token errors here
  res.status(403)
  res.json({err: "CSRF ERROR"}) // respond with JSON response
})
Thus, We have successfully added CSRF validation logic as middleware to verify the request before being executed. For bugs/hugs, feel free to comment below. Share is care.

Sunday, March 07, 2021

Integrating Google Recaptcha with ExpressJS

Fighting spam and bots over the internet is a never-ending problem and that's why companies like Cloudflare kick-off their journey from the building/contributing honeypot to IPO. However, there are other few ways to prevent spam API calls, brute force attacks and they are solving captchas, and Google is one of the pioneers in providing better user experience plus spam prevention techniques. There are other online services such as Funcaptcha captcha as a service for SaaS companies.

Today, let's see about implementing Google ReCaptcha with expressjs Node server as middleware and rendering them in forms.

Integrating Google Recaptcha with ExpressJS
Integrating Google Recaptcha with ExpressJS 

Installation

npm install express-recaptcha --save

Setup:

Signup for Google Account and click here to create new Recaptcha keys and specific to Version 3. Enter the domain including localhost for testing purposes and grab the Site key and Secret key to access Recaptcha APIs from Nodejs backend.

var Recaptcha = require('express-recaptcha').RecaptchaV3;

var recaptcha = new Recaptcha('SITE_KEY', 'SECRET_KEY');

Frontend Client setup

As the client-side is so specialized and varies from ReactJS, Vue, or plain vanilla javascript, I recommend you to follow Google docs to implement them.

Server Validation

As this blog post covers primarily server validation logic, ExpressJS provides excellent integration with middleware where the Recaptcha validation can be added to the routes before even route logic executes.

app.post('/', recaptcha.middleware.verify, function(req, res){
  if (!req.recaptcha.error) {
    // success code
  } else {
    // error code
  }
});
As mentioned before, the middleware function that contains Recaptcha verification executes first and the results are attached to the request object for implementing the business logic. One could use the req.recaptcha.error object to verify if the Recaptcha request is successful.

Req.recaptcha object

{
  error: string, // error code (see table below), null if success
  data: {
    hostname: string, // the site's hostname where the reCAPTCHA was solved
    score: number, // the score for this request (0.0 - 1.0)
    action: string // the action name for this request (important to verify)
  }
}
Feel free to follow the npm package of Express Recaptcha for more details and customization logic.

For bugs/hugs, feel free to comment below. Share is care.