Skip to main content

Insecurely generated cookies - Secure

Need

Secure generation and transmission of cookies

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('/login', (req, res) => {
const username = req.query.username;
const password = req.query.password;

// Perform authentication logic...

// Set insecure cookie
res.cookie('session', '1234567890', { httpOnly: true });

res.send('Login successful');
});

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

The vulnerability in this code is that it sets a sensitive cookie, named 'session', without the 'Secure' attribute. The 'Secure' attribute is used to ensure that the cookie is only sent over a secure (HTTPS) connection.

By not setting the 'Secure' attribute, the cookie can be sent over an insecure channel, such as an HTTP connection. This makes it vulnerable to a Man-in-the-Middle (MiTM) attack. An attacker could intercept the cookie and obtain sensitive information, such as the session identifier, by eavesdropping on the network traffic.

In this code, the vulnerable line is:

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

To fix this vulnerability, the 'Secure' attribute should be added to the cookie options. This can be done by modifying the code as follows:

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

By setting the 'secure' option to true, the cookie will only be sent over a secure (HTTPS) connection, mitigating the vulnerability.

Steps

  • Import the 'cookie-parser' package
  • Add the 'cookie-parser' middleware to the Express app
  • Set the 'secure' option to 'true' when setting the 'session' cookie

Compliant code

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

const app = express();
app.use(cookieParser());

app.get('/login', (req, res) => {
const username = req.query.username;
const password = req.query.password;

// Perform authentication logic...

// Set secure cookie
res.cookie('session', '1234567890', { httpOnly: true, secure: true });

res.send('Login successful');
});

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

The fixed code addresses the vulnerability by setting the secure attribute in the cookie options when setting a sensitive cookie.

First, the code imports the necessary modules, express and cookie-parser, which are used to handle cookies in the application.

The code creates an instance of the Express application and uses the cookieParser middleware to parse incoming cookies.

Next, there is a route handler for the /login endpoint. Inside the handler, the code retrieves the username and password from the query parameters, which are typically obtained from a login form.

After performing the authentication logic, the code sets a secure cookie using the res.cookie method. The secure option is set to true, indicating that the cookie should only be sent over a secure (HTTPS) connection. This ensures that the cookie is not sent through an insecure channel, mitigating the vulnerability.

Finally, a response is sent to the client with the message "Login successful".

The code also starts the Express server on port 3000 and logs a message to indicate that the server is running.

By setting the secure attribute to true in the cookie options, the fixed code ensures that sensitive cookies are only sent over a secure channel, preventing potential attackers from intercepting them and obtaining sensitive information.

References