Skip to main content

Insecurely generated cookies - SameSite

Need

Secure generation of cookies with proper SameSite attribute

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and APIs

Description

Non compliant code

import express from 'express';

const app = express();

app.get('/', (req, res) => {
res.cookie('session', '1234567890', { httpOnly: true });
res.send('Hello World!');
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The vulnerability in this code is that the cookies generated by the application do not have the SameSite attribute properly set. The SameSite attribute is used to prevent cross-site request forgery (CSRF) attacks by specifying whether the cookie should be sent with cross-site requests.

In this code, the res.cookie function is used to set a cookie named "session" with the value "1234567890". However, the SameSite attribute is not specified, which means that the cookie will be sent with both same-site and cross-site requests.

This vulnerability can be exploited by an attacker to perform a CSRF attack. In a CSRF attack, the attacker tricks a user into performing unwanted actions on a website where the user is authenticated. By not setting the SameSite attribute, the application is vulnerable to CSRF attacks because the browser will send the cookie with cross-site requests, allowing an attacker to impersonate the user and perform actions on their behalf.

To fix this vulnerability, the application should set the SameSite attribute in the cookie options. The SameSite attribute should be set to "Strict" or "Lax" depending on the desired level of protection. For example, to set the SameSite attribute to "Strict", the code should be modified as follows:

res.cookie('session', '1234567890', { httpOnly: true, sameSite: 'Strict' });

By setting the SameSite attribute properly, the application can mitigate the risk of CSRF attacks by ensuring that the cookie is only sent with same-site requests.

Steps

  • Install the cookie-parser package: npm install cookie-parser
  • Import the cookie-parser module: import cookieParser from 'cookie-parser';
  • Add the cookie-parser middleware to the application: app.use(cookieParser());
  • Set the sameSite attribute to strict when setting the cookie: res.cookie('session', '1234567890', { httpOnly: true, sameSite: 'strict' });

Compliant code

import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();

app.use(cookieParser());

app.get('/', (req, res) => {
res.cookie('session', '1234567890', { httpOnly: true, sameSite: 'strict' });
res.send('Hello World!');
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The fixed code addresses the vulnerability by properly setting the SameSite attribute in the cookies.

First, the code imports the necessary modules, including express and cookie-parser, which is used to parse cookies in the incoming requests.

Then, an instance of the express application is created.

The code uses the cookieParser middleware, which parses the cookies from the incoming requests and makes them available in the req.cookies object.

Next, a route handler is defined for the root path ('/'). Inside the handler, the res.cookie method is used to set a cookie named 'session' with the value '1234567890'. The { httpOnly: true, sameSite: 'strict' } options are passed as the third argument to the res.cookie method.

The httpOnly option ensures that the cookie is only accessible through HTTP requests and cannot be accessed by client-side JavaScript, which helps to prevent cross-site scripting (XSS) attacks.

The sameSite option is set to 'strict', which means that the cookie will only be sent in requests that originate from the same site as the server. This helps to mitigate cross-site request forgery (CSRF) attacks by preventing the browser from automatically including the cookie in cross-site requests.

Finally, the response is sent with the message 'Hello World!'.

The app.listen method is used to start the server on port 3000, and a console.log statement is added to indicate that the server is running.

Overall, the fixed code properly sets the SameSite attribute in the cookies by using the 'strict' value, which helps to mitigate CSRF attacks.

References