Insecurely generated token - JWT - TypeScript

Insecurely generated token - JWT - TypeScript

Need

Secure token generation for user creation service

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();

const weakKey = 'insecure_key'; // Weak key used for signing the token

app.post('/createUser', (req, res) => {
  const user = req.body;

  // Generate token with weak key
  const token = jwt.sign(user, weakKey);

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

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

The vulnerability in this code lies in the insecure generation of the JSON Web Token (JWT) used for user creation.

The weakKey variable is used as the secret key for signing the token. However, this key is hardcoded and is set to 'insecure_key', which is a weak and easily guessable value.

As a result, an attacker who knows the weak key can easily generate a valid token with arbitrary user data and modify token parameters such as the expiration date. This allows the attacker to impersonate a legitimate user and consume the user creation service within the application.

To address this vulnerability, it is recommended to use strong and securely generated passwords for signing and verifying the user creation token.

Steps

  • Generate a strong and secure key for signing the token
  • Replace the weak key with the strong key in the code
  • Ensure the strong key is kept secret and not exposed in the code
  • Update the code to use the strong key for signing the token

Compliant code

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

const app = express();

// Generate a strong and secure key for signing the token
const strongKey = crypto.randomBytes(64).toString('hex');

app.post('/createUser', (req, res) => {
  const user = req.body;

  // Use the strong key for signing the token
  const token = jwt.sign(user, strongKey);

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

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

The fixed code addresses the vulnerability by implementing secure token generation using a strong and secure key. Here's an explanation of the changes made:

1. The code imports the necessary modules: express for creating the server, jsonwebtoken for generating and verifying tokens, and crypto for generating a strong key.

2. A strong and secure key is generated using crypto.randomBytes(64).toString('hex'). This generates a random sequence of 64 bytes and converts it to a hexadecimal string. This key will be used for signing the token.

3. The server is created using express().

4. The /createUser route is defined as a POST request. When this route is accessed, the request body is expected to contain user data.

5. The jwt.sign() function is used to generate a token. The user object is passed as the payload, and the strongKey is used for signing the token. This ensures that the token is securely generated.

6. The generated token is sent as a JSON response to the client.

7. The server listens on port 3000 for incoming requests.

By generating a strong and secure key for signing the token, the fixed code ensures that the token cannot be easily tampered with or forged by an attacker. This mitigates the vulnerability of insecurely generated tokens.

References