CWE-916: Use of Password Hash With Insufficient Computational Effort
Learn about CWE-916 (Use of Password Hash With Insufficient Computational Effort), its security impact, exploitation methods, and prevention guidelines.
What is Use of Password Hash With Insufficient Computational Effort?
• Overview: This vulnerability occurs when a password hashing scheme is used that doesn't require enough computational effort, making it easier for attackers to crack passwords through brute force or other methods.
• Exploitation Methods:
- Attackers can exploit this vulnerability by obtaining password hashes through techniques like SQL injection and then performing offline attacks to crack the passwords.
- Common attack patterns include dictionary attacks, brute force attacks, and using precomputed hash lists like rainbow tables.
• Security Impact:
- Direct consequences include unauthorized access to user accounts if passwords are cracked.
- Potential cascading effects include exposure of sensitive data, identity theft, and further compromise of systems.
- Business impact can include loss of reputation, legal liabilities, and financial losses due to data breaches.
• Prevention Guidelines:
- Use strong, computationally intensive hash algorithms like bcrypt, Argon2, or PBKDF2, which incorporate salting and stretching.
- Implement salting to ensure that each password hash is unique, even if users have the same password.
- Follow security best practices by regularly updating hashing algorithms and configurations in line with current security research.
- Recommended tools and frameworks include libraries that support secure password hashing, such as the cryptography library in Python or the bcrypt library in Node.js.
Technical Details
Likelihood of Exploit: Not specified
Affected Languages: Not Language-Specific
Affected Technologies: Not specified
Vulnerable Code Example
import hashlib
def store_password_vulnerable(password):
# Vulnerable: Using SHA-256 for password hashing, which is fast and not suitable for passwords
# SHA-256 is designed to be fast, which makes it vulnerable to brute-force and dictionary attacks
hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest()
return hashed_password
Explanation:
- The code uses SHA-256 to hash passwords. While SHA-256 is a cryptographically secure hash function, it is designed for speed, making it unsuitable for password hashing. Fast hashing algorithms are susceptible to brute-force and dictionary attacks because they can be computed quickly, allowing attackers to try many password guesses in a short amount of time.
How to fix Use of Password Hash With Insufficient Computational Effort?
To properly fix this vulnerability, we should use a password hashing algorithm that is intentionally slow and incorporates a salt to protect against rainbow table attacks. Best practices recommend using a key derivation function like bcrypt
, scrypt
, or Argon2
. These algorithms are designed to be computationally expensive and include a built-in mechanism for salting the hashes.
- Bcrypt: A widely used password hashing library that automatically handles salting and is computationally expensive.
- Scrypt: An alternative that is designed to be memory-hard as well, providing additional resistance to attacks using specialized hardware.
- Argon2: The winner of the Password Hashing Competition and currently considered one of the strongest password hashing functions.
Fixed Code Example
import bcrypt
def store_password_secure(password):
# Fixed: Using bcrypt for password hashing, which is slow and includes a salt by default
# bcrypt automatically handles salting the password and is designed to be computationally expensive
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
return hashed_password
Explanation:
- The
bcrypt.hashpw()
function is used to hash the password. It automatically handles salting and ensures the hash is computationally expensive to compute, making it resistant to brute-force attacks. bcrypt.gensalt()
: Generates a salt with a default cost factor, which determines the complexity of the hash. A higher cost factor increases security by making the hash more computationally expensive.
By switching to bcrypt
, we ensure that our password storage is secure against common attack vectors that exploit fast hashing algorithms. This approach significantly increases the time and resources required for an attacker to crack the password hashes.