Weak credential policy
Need
Enforcement of a strong password policy, covering password complexity requirements and secure temporary password handling
Context
• Usage of TypeScript for adding static typing to JavaScript
• Usage of Express for building web applications and handling HTTP requests
• Usage of bcrypt for password hashing and encryption
Description
1. Non compliant code
# --- Password strength ---
import express from 'express';
import bcrypt from 'bcrypt';
const app = express();
app.post('/register', (req, res) => {
const { username, password } = req.body;...**Password strength:** The vulnerability in the given code is a weak credential policy regarding password strength. The code does not enforce any password strength requirements, allowing users to assign weak passwords to their accounts. In the code, the user's password is stored as is, without any hashing or encryption. This means that the password is stored in plain text format, making it easily readable if an attacker gains access to the database. By not enforcing password strength requirements, such as minimum length, complexity, or the use of phrases instead of word-based passwords, the code allows users to choose weak passwords that can be easily guessed or cracked through brute force or dictionary attacks. To address this vulnerability, it is recommended to establish a policy for credential creation that involves phrases and not word-based passwords. Additionally, the passwords should be properly hashed and encrypted before storing them in the database to ensure the security of user credentials. **Temporary passwords:** The vulnerability in this code is related to weak credential policy for temporary passwords. The code generates a temporary password using the `generateTemporaryPassword` function, which currently returns a weak password "weak123". This weak password does not meet the recommended best practices for strong passwords, such as having a combination of uppercase and lowercase letters, numbers, and special characters. Furthermore, the code does not implement any security measures for storing the temporary password in the database. The `saveTemporaryPassword` function does not hash or encrypt the password before saving it, leaving it vulnerable to unauthorized access if the database is compromised. Additionally, the code does not implement any secure email sending mechanism in the `sendTemporaryPassword` function. This means that the temporary password could be intercepted or accessed by unauthorized individuals during the email transmission process. These vulnerabilities can allow an attacker to compromise the temporary passwords and gain unauthorized access to the application, potentially leading to unauthorized actions or data breaches.
2. Steps
• Implement a password strength policy that enforces minimum requirements for password complexity.
• Use a secure password hashing algorithm, such as bcrypt, to store the user's password in the database.
• Update the code to hash the user's password using bcrypt before storing it in the database.
• Validate the strength of the password before accepting it for registration.
• Consider using a password strength meter to provide feedback to the user during registration.
• Implement a strong password generation function for generating temporary passwords.
• Implement secure password storage mechanism to store temporary passwords in the database.
• Implement a secure email sending mechanism to send temporary passwords to users.
3. Secure code example
# --- Password strength ---
import express from 'express';
import bcrypt from 'bcrypt';
const app = express();
app.use(express.json());
...**Password strength:** The fixed code addresses the vulnerability by implementing a password strength policy and using bcrypt to securely hash the passwords before storing them in the database. Here's how the code works: 1. The code imports the necessary modules, including `express` for creating the server and `bcrypt` for password hashing. 2. The code creates an instance of the Express application. 3. The code adds middleware to parse incoming JSON data. 4. The code defines a POST route at `/register` to handle user registration. 5. Inside the route handler, the code extracts the `username` and `password` from the request body. 6. The code defines a regular expression `passwordRegex` to enforce the minimum requirements for password complexity. The regex pattern ensures that the password contains at least one lowercase letter, one uppercase letter, one digit, one special character, and is at least 8 characters long. 7. The code checks if the provided password matches the password complexity requirements using the `test` method of the `passwordRegex`. If the password does not meet the requirements, the code returns a 400 status code with a JSON response indicating the error. 8. If the password meets the requirements, the code proceeds to hash the password using bcrypt's `hash` function. The `hash` function takes the password and a salt round value of 10, which determines the computational cost of generating the hash. 9. The code then saves the user's credentials to the database (database code not shown). 10. If everything is successful, the code sends a 200 status code with a JSON response indicating successful registration. 11. If any errors occur during the process, the code catches the error, logs it to the console, and sends a 500 status code with a JSON response indicating an internal server error. 12. Finally, the code starts the server and listens on port 3000. By enforcing a password strength policy and securely hashing the passwords, the fixed code mitigates the vulnerability related to weak credential policy. **Temporary passwords:** The fixed code addresses the vulnerability by implementing secure temporary passwords using recommended best practices. Here's an explanation of the changes made: 1. The code imports the necessary modules: `express` for creating the server, `bcrypt` for hashing passwords securely, and `nodemailer` for sending emails. 2. The `/login` route is defined as a POST request handler. It expects the `username` and `password` to be provided in the request body. 3. The `generateTemporaryPassword` function generates a temporary password of length 10 using a random alphanumeric string. 4. The `saveTemporaryPassword` function takes the `username` and `temporaryPassword` as parameters. It uses the `bcrypt` library to hash the temporary password with a salt of 10 rounds before storing it in the database. The use of bcrypt ensures that the password is securely hashed and not easily reversible. 5. The `sendTemporaryPassword` function takes the `username` and `temporaryPassword` as parameters. It uses the `nodemailer` library to create a transporter object with the email service credentials. It then defines the email options, including the sender, recipient, subject, and body of the email. The temporary password is included in the email body. 6. The `/login` route handler calls the `generateTemporaryPassword` function to generate a temporary password. It then calls the `saveTemporaryPassword` function to securely hash and store the temporary password in the database. Finally, it calls the `sendTemporaryPassword` function to send the temporary password to the user's email. 7. The server listens on port 3000 and logs a message when it starts running. By implementing these changes, the code ensures that temporary passwords are securely generated, hashed, and stored in the database. Additionally, the temporary password is sent to the user's email using a secure email service.
References
• 035. Weak credential policy