Safeguard
Application Security•

CWE-916 Password Hash With Insufficient Computational Effort

Fast hashes make stolen password databases easy to crack. CWE-916 explains stretching, salting, memory-hard functions and how to move to bcrypt, scrypt or PBKDF2.

Safeguard Security Team
5 min read

CWE-916, Use of Password Hash With Insufficient Computational Effort, applies when a product hashes passwords with a scheme that does not demand enough work to make cracking infeasible or expensive. If you store user passwords, you are in scope.

How it happens

Most systems store a hash, not the password. At login they hash the submitted password and compare. That is the right design. The trouble is the choice of hash.

MITRE explains that many hash algorithms are built to run quickly with minimal overhead, even cryptographic ones. For password storage that speed helps the attacker. Suppose someone gets the hashes through another flaw, such as SQL injection on the database that holds them. They can take the hashes offline and compute guesses at huge rates using parallel cloud computing and GPU, ASIC or FPGA hardware. Without built-in work, they can try large numbers of guesses or even exhaust the entire password space very quickly.

MITRE lists the properties that matter against that kind of offline attack:

  • The CPU time needed to compute the hash, called stretching.
  • The memory needed, called memory-hard operations.
  • A random value included with the password, called salting.

The observed CVEs show what weak schemes looked like in real products:

  • CVE-2008-1526 (details) and CVE-2006-1058: routers did not use a salt with a hash, making passwords easier to crack.
  • CVE-2008-4905: blogging software used a hard-coded salt when calculating a password hash.
  • CVE-2002-1657: a database server used the username as the salt, simplifying brute force attacks.

A salt that is the same for everyone, or predictable, does little. It needs to be random and unique per password.

# Weak: fast hash, no per-user salt
import hashlib
stored = hashlib.md5(password.encode()).hexdigest()
# Better: a slow, salted, adaptive scheme (bcrypt library)
import bcrypt
stored = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
ok = bcrypt.checkpw(candidate.encode(), stored)

bcrypt generates a random salt and embeds it in the stored value, and rounds sets how much work each hash costs.

What an attacker gains

MITRE lists access control impact: bypass a protection mechanism and gain privileges or assume identity. If attackers obtain the hashes, insufficient computational effort makes brute force easier, using techniques such as rainbow tables or specialized hardware such as GPUs. Cracked passwords are then used to log in as the real users, and users who reuse passwords carry the damage to other services.

How to find it

MITRE lists several detection approaches, mostly manual or static:

  • Source code analysis with a weakness analyzer, which MITRE rates as highly cost effective.
  • Focused manual review of the source, also rated highly cost effective.
  • For binaries and bytecode, disassembly and weakness analysis give partial coverage.

A quick audit: find where passwords are hashed and read the function being called. Look for MD5, SHA-1 or a single round of SHA-256 over a password, for a missing or constant salt, and for a salt derived from the username. Then check the stored values in the database. A column of 32 or 40 hex characters is a warning sign.

How to fix it

From the MITRE mitigations:

  1. Use an adaptive hash function that can be configured to change the work needed to compute the hash, through the number of iterations (stretching) or the memory required. Some functions salt automatically. These raise the cost of brute force greatly compared with intentionally fast functions such as MD5, and can make rainbow table attacks infeasible. Because computing power grows, the work factor can be raised later without replacing the algorithm.
  2. Candidates MITRE names are bcrypt, scrypt and PBKDF2. It notes there is active debate over which is most effective, and that all are stronger than a salt on a low-cost hash. MITRE rates this mitigation as highly effective.
  3. When using industry approved techniques, use them correctly. Do not skip resource intensive steps. They are often essential against common attacks.
  4. Plan for performance. MITRE warns these functions have an impact and need care to avoid denial of service. Their configurability gives finer control over CPU and memory use, so tune it for your environment, and rate limit login attempts.

To migrate existing users without a reset, hash the old hash with the new scheme, or upgrade each account at its next successful login and mark the stored scheme in the record.

Quick check

Why is a fast hash bad for passwords?

It lets an attacker with stolen hashes try enormous numbers of guesses offline, quickly and cheaply.

Does a salt alone solve the problem?

No. MITRE says the adaptive functions are stronger than a salt used with a low-cost hash. You need both a unique salt and real work per guess.

Which functions does MITRE name?

bcrypt, scrypt and PBKDF2.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.