logo

Business information leak - Token - Typescript


Need

Protection of sensitive user information in session tokens


Context

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

Description

Insecure Code Example

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

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

Secure Code Example

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

  • 220 - Business information leak - Token

  • Last updated

    2023/09/18