Guessed weak credentials - TypeScript

Guessed weak credentials - TypeScript

Need

Enhancement of credential security

Context

  • Usage of TypeScript for type-checking and compiling JavaScript code
  • Usage of Express for building web applications and APIs

Description

Non compliant code

        import express from 'express';

const app = express();

app.post('/login', (req, res) => {
  const { username, password } = req.body;

  if (username === 'admin' && password === '123456') {
    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 it uses weak credentials for the login functionality. The username is set to 'admin' and the password is set to '123456'. These credentials are easily guessable and can be exploited by an attacker using brute force techniques.

An attacker can automate the process of guessing different combinations of usernames and passwords until they find a match. Since the credentials used in this code are weak, the attacker can quickly guess them and gain unauthorized access to the system.

To mitigate this vulnerability, it is recommended to enforce a strong password policy. This includes configuring a minimum and maximum length for passwords, avoiding word-based passwords, not using usernames in passwords, and not reusing passwords. By implementing these measures, the system can ensure that users choose strong and unique passwords, making it harder for attackers to guess them.

Steps

  • Enforce a strong password policy by implementing password complexity requirements.
  • Remove hard-coded credentials from the code.
  • Implement a secure authentication mechanism such as bcrypt for password hashing and salting.
  • Consider implementing multi-factor authentication for an added layer of security.
  • Regularly update and patch the application and its dependencies to address any security vulnerabilities.
  • Monitor and log failed login attempts to detect and respond to potential brute force attacks.
  • Consider implementing account lockout mechanisms to prevent brute force attacks.
  • Educate users about the importance of strong and unique passwords and encourage them to regularly change their passwords.

Compliant code

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

const app = express();

app.use(express.json());

app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // Retrieve the hashed password from the database
  const hashedPassword = 'hashed_password_from_database';

  // Compare the provided password with the hashed password
  bcrypt.compare(password, hashedPassword, (err, result) => {
    if (err) {
      console.error(err);
      res.status(500).send('Internal Server Error');
      return;
    }

    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 implementing a secure password authentication mechanism using bcrypt.

1. The code imports the necessary modules, including 'express' for creating the server and 'bcrypt' for hashing and comparing passwords.

2. The code creates an instance of the express application and sets it up to parse JSON data.

3. The code defines a POST route '/login' for handling login requests. It extracts the username and password from the request body.

4. The code retrieves the hashed password from the database. In this example, the hashed password is hardcoded for demonstration purposes. In a real application, it would be fetched from a secure database.

5. The code uses the bcrypt.compare function to compare the provided password with the hashed password. This function securely compares the two values without revealing the actual password.

6. If there is an error during the comparison process, the code logs the error and sends a 500 Internal Server Error response.

7. If the comparison is successful (result is true), the code sends a 'Login successful' response.

8. If the comparison fails (result is false), the code sends an 'Invalid credentials' response.

9. The code starts the server and listens on port 3000.

By using bcrypt to hash and compare passwords, the code ensures that even if an attacker gains access to the hashed passwords, it would be computationally infeasible to guess the original passwords. Additionally, the code does not reveal any information about the password during the comparison process, enhancing security.

References