Skip to main content

Business information leak - Token

Need

Protection of sensitive user information in session tokens

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and APIs
  • Usage of jsonwebtoken for generating and verifying JSON Web Tokens (JWT)

Description

Non compliant code

import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();

app.get('/login', (req, res) => {
const { username, email, fullName } = req.body;

// Include sensitive user information in the session token
const token = jwt.sign({ username, email, fullName }, 'secretKey');

res.json({ token });
});

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

The vulnerability in this code is that sensitive user information, such as the username, email, and full name, is included in the session token.

In the code, when a user logs in, the username, email, and fullName are extracted from the request body. Then, using the jsonwebtoken library, these sensitive user details are signed into a token using a secret key. Finally, the token is sent back as a response to the client.

The problem with this approach is that session tokens are often stored on the client-side, either in cookies or local storage. Including sensitive user information in the token means that if an attacker gains access to the token, they can easily extract and view the user's username, email, and full name.

This can lead to a business information leak, as an attacker could obtain and misuse this information for malicious purposes, such as identity theft, phishing attacks, or spamming.

To fix this vulnerability, it is recommended to avoid including sensitive user information in the session token. Instead, the token should only contain a unique identifier or reference to the user, and the sensitive user details should be stored securely on the server-side.

Steps

  • Remove sensitive user information from the session token
  • Store sensitive user information securely on the server
  • Generate a unique session identifier and include it in the session token
  • Encrypt the session token to protect the data
  • Implement proper authentication and authorization mechanisms

Compliant code

import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();

app.use(express.json());

app.get('/login', (req, res) => {
const { username, email, fullName } = req.body;

// Generate a unique session identifier
const sessionId = generateSessionId();

// Store sensitive user information securely on the server
storeUserInformation(username, email, fullName, sessionId);

// Generate the session token
const token = generateSessionToken(sessionId);

res.json({ token });
});

function generateSessionId() {
// Generate a unique session identifier
// Implement your own logic here
return 'uniqueSessionId';
}

function storeUserInformation(username, email, fullName, sessionId) {
// Store sensitive user information securely on the server
// Implement your own logic here
}

function generateSessionToken(sessionId) {
// Generate the session token
const token = jwt.sign({ sessionId }, 'secretKey');

// Encrypt the session token to protect the data
// Implement your own encryption logic here

return token;
}

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

The fixed code addresses the vulnerability by avoiding the inclusion of sensitive user information in the session token. Here's an explanation of the changes made:

  1. The code imports the necessary modules, including express for creating the server and jsonwebtoken for generating and verifying tokens.

  2. The express.json() middleware is used to parse incoming JSON requests.

  3. The /login route is defined as a POST request handler. It expects the username, email, and fullName to be provided in the request body.

  4. A unique session identifier (sessionId) is generated using the generateSessionId() function. This function should be implemented with your own logic to generate a unique identifier.

  5. The sensitive user information (username, email, fullName, sessionId) is stored securely on the server using the storeUserInformation() function. This function should be implemented with your own logic to securely store the user information.

  6. The generateSessionToken() function is called to generate the session token. It takes the sessionId as input and uses the jsonwebtoken library to sign the token with a secret key. You should replace 'secretKey' with your own secret key.

  7. The session token is returned as a JSON response to the client.

  8. The server is set to listen on port 3000.

By avoiding the inclusion of sensitive user information in the session token, the fixed code mitigates the risk of a business information leak vulnerability.

References