logo

Non-encrypted confidential information - Credentials - Typescript


Need

Secure storage of credentials


Context

  1. Usage of TypeScript for statically typed JavaScript development
  2. Usage of Express for building web applications and APIs

Description

Insecure Code Example

import express from 'express';

const app = express();

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

  // Vulnerability: Storing passwords in plain text
  const storedPassword = 'secretpassword';

  if (password === storedPassword) {
    res.send('Login successful');
  } else {
    res.send('Invalid credentials');
  }
});

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

The vulnerability in this code is that the passwords are stored in plain text in the source code. In the `app.get('/login')` route handler, the code retrieves the username and password from the query parameters of the request. It then compares the password with a stored password, which is hardcoded as 'secretpassword'. Storing passwords in plain text is a security risk because if an attacker gains access to the source code or the server, they can easily view the passwords without any encryption. This allows them to obtain sensitive information and potentially compromise resources or services. To mitigate this vulnerability, it is recommended to avoid storing sensitive information, such as passwords, in the source code. Instead, sensitive information should be stored securely, such as in a separate configuration file or a database, and accessed securely when needed. Additionally, it is important to ensure that sensitive information is not included in the source code repository or exposed in any other way.

Steps

  1. Remove the plain text password stored in the code
  2. Implement a secure password storage mechanism such as hashing and salting
  3. Use a secure authentication method such as bcrypt to compare passwords
  4. Consider using a secure session management library for handling user sessions
  5. Ensure that sensitive information, API keys, and passwords are not included in the source code or online code repositories

Secure Code Example

import express from 'express';
import bcrypt from 'bcrypt';

const app = express();

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

  // Secure password storage using bcrypt
  const hashedPassword = '$2b$10$Y5W4Nz3Xz6i6q4Z0OJ5z7eG1f2R3X5Z6C7V8b9N0M1L2K3J4H5G6F7E8D9C0B';

  bcrypt.compare(password, hashedPassword, (err, result) => {
    if (err) {
      res.send('Error occurred during login');
    } else if (result) {
      res.send('Login successful');
    } else {
      res.send('Invalid credentials');
    }
  });
});

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

The fixed code addresses the vulnerability by securely storing passwords using the bcrypt library. Here's an explanation of the changes made: 1. The code imports the necessary modules, `express` and `bcrypt`, to handle the server and password hashing respectively. 2. The code creates an instance of the Express application using `express()`. 3. The code defines a route for the `/login` endpoint using `app.get('/login', ...)`. This route handles the login functionality. 4. Inside the route handler, the code retrieves the `username` and `password` from the query parameters of the request. 5. The code securely stores the hashed password in a variable called `hashedPassword`. This hashed password is a placeholder and should be replaced with the actual hashed password stored in a secure manner (e.g., in a database). 6. The code uses the `bcrypt.compare()` function to compare the provided password with the hashed password. This function takes care of the password comparison securely, using the bcrypt algorithm. 7. Inside the callback function of `bcrypt.compare()`, the code checks for any errors that might occur during the comparison. If an error occurs, it sends an error response to the client. 8. If the comparison is successful (i.e., the passwords match), the code sends a "Login successful" response to the client. 9. If the comparison fails (i.e., the passwords do not match), the code sends an "Invalid credentials" response to the client. 10. The code starts the server by calling `app.listen(3000, ...)`, which listens for incoming requests on port 3000. 11. Finally, the code logs a message to the console indicating that the server is running. By using bcrypt to securely hash and compare passwords, the fixed code ensures that sensitive information, such as passwords, is not stored in plain text and is protected against unauthorized access.


References

  • 249 - Non-encrypted confidential information - Credentials

  • Last updated

    2023/09/18