CWE-836: Use of Password Hash Instead of Password for Authentication

Learn about CWE-836 (Use of Password Hash Instead of Password for Authentication), its security impact, exploitation methods, and prevention guidelines.

What is Use of Password Hash Instead of Password for Authentication?

• Overview: Use of Password Hash Instead of Password for Authentication (CWE-836) occurs when a system relies on the client to generate a password hash, which is then compared to a stored hash on the server, potentially allowing attackers to authenticate without the actual password.

• Exploitation Methods:

  • Attackers can exploit this vulnerability by obtaining the password hash through methods such as SQL injection or information exposure.
  • Common attack patterns include hash replay attacks, where attackers use a modified client to send the stolen hash, bypassing the need to know the actual password.

• Security Impact:

  • Direct consequences of successful exploitation include unauthorized access to accounts or systems.
  • Potential cascading effects could involve further data breaches or lateral movement within the network.
  • Business impact might include loss of customer trust, financial losses, and legal implications due to compromised data security.

• Prevention Guidelines:

  • Specific code-level fixes include ensuring that password hashing is done server-side, not client-side.
  • Security best practices involve using secure communication protocols (e.g., HTTPS) to protect data in transit and applying additional authentication factors (e.g., multi-factor authentication).
  • Recommended tools and frameworks include using libraries that handle password hashing securely, such as bcrypt or Argon2, and implementing secure password storage and verification mechanisms.
Corgea can automatically detect and fix Use of Password Hash Instead of Password for Authentication in your codebase. [Try Corgea free today](https://corgea.app).

Technical Details

Likelihood of Exploit: Not specified

Affected Languages: Not Language-Specific

Affected Technologies: Not specified

Vulnerable Code Example

import hashlib

def authenticate_user(stored_hash, received_hash):
    """
    Vulnerable function: This function compares a received hash directly with the stored hash.
    This assumes the client is sending a hash of the password, which exposes the system to replay attacks.
    """
    # Compare the received password hash with the stored password hash
    return stored_hash == received_hash

Explanation:

  • Line 3-6: The function authenticate_user takes a stored_hash and a received_hash as parameters. This design flaw assumes the client sends a hash of the password, which can be exploited by an attacker who sends a precomputed hash directly, bypassing the need to know the actual password. This approach is vulnerable to replay attacks.

How to fix Use of Password Hash Instead of Password for Authentication?

The vulnerability arises from directly comparing hashes received from the client with stored password hashes. This approach is insecure because it assumes that the client can be trusted to generate the hash correctly and securely. Instead, the client could send a precomputed hash that matches the stored hash, bypassing the need for knowing the actual password.

Correct Approach:

  1. Do not send password hashes from the client: Always send the raw password over a secure channel (e.g., HTTPS) and compute the hash server-side.
  2. Use a strong password hashing algorithm: Use algorithms like bcrypt, Argon2, or PBKDF2, which are designed to be slow and resist brute-force attacks.
  3. Salting and hashing: Always salt and hash passwords before storing them in the database to prevent the use of rainbow tables.
  4. Secure communication: Ensure that all communications between client and server are encrypted using TLS/SSL to prevent interception of passwords.

Fixed Code Example

import bcrypt

def authenticate_user(stored_hash, password):
    """
    Fixed function: This function now takes the raw password and hashes it server-side,
    comparing it securely with the stored hash.
    """

    # Hash the received password with bcrypt and compare it to the stored hash
    # bcrypt automatically handles the salt internally
    return bcrypt.checkpw(password.encode('utf-8'), stored_hash.encode('utf-8'))

Explanation:

  • Line 3: Importing bcrypt, a library specifically designed for secure password hashing.
  • Line 6-10: The function authenticate_user now expects a raw password input instead of a hash. The bcrypt.checkpw() function securely compares the plaintext password against the stored hash. It automatically handles salting and hashing, ensuring that the authentication process is secure. This prevents the client from sending precomputed hashes and mitigates the risk of replay attacks.
Corgea Logo

Find this vulnerability and fix it with Corgea

Scan your codebase for CWE-836: Use of Password Hash Instead of Password for Authentication and get remediation guidance

Start for free and no credit card needed.