MD5 Used for Password Hashing

HIGH

MD5 is being used to hash passwords. MD5 is cryptographically broken and orders of magnitude too fast for password hashing. Use bcrypt, scrypt, or argon2.

Rule Information

Language
Python
Category
Python Core
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythonmd5password-hashingweak-password-storagecredentialsCWE-916OWASP-A02
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset python/PYTHON-LANG-SEC-034 --project .
1
2
3
4
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

About This Rule

Understanding the vulnerability and how it is detected

Using MD5 to hash passwords is a critical vulnerability. MD5 has two fatal properties for password hashing: it is cryptographically broken (collision attacks exist) and it is extremely fast (modern GPUs can compute billions of MD5 hashes per second).

Password hashing requires a slow, memory-hard function specifically designed to resist brute-force attacks. bcrypt, scrypt, and Argon2 are purpose-built for this: they are deliberately slow, use significant memory, and have configurable work factors that can be increased as hardware improves.

This rule detects patterns where hashlib.md5() is called in proximity to password-related variables, functions, or context, indicating MD5 is being used for credential storage. Even salted MD5 is insufficient — a salted MD5 database can be cracked in hours using GPU clusters.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Trivial Database Cracking After Breach

A leaked database of MD5-hashed passwords can be completely cracked in hours to days using GPU-based tools like hashcat. Modern GPUs compute 50+ billion MD5 hashes per second, making even complex passwords vulnerable to brute force within hours.

2

Rainbow Table Attacks on Unsalted Passwords

Without a unique per-user salt, common passwords have identical MD5 hashes across all users. Precomputed rainbow tables covering hundreds of millions of common passwords are freely available, enabling instant cracking of any password whose MD5 hash is in the table.

3

Credential Stuffing Risk

Once cracked from a MD5 hash database, plaintext passwords can be used in credential stuffing attacks against other services where users reuse passwords, amplifying the damage beyond the original breach.

4

Compliance Violations

Storing passwords with MD5 violates PCI DSS, NIST SP 800-63B, and most data protection regulations that mandate strong, modern password hashing. A breach of MD5-hashed passwords triggers mandatory notification requirements under GDPR and similar laws.

How to Fix

Recommended remediation steps

  • 1Replace MD5 password hashing with argon2-cffi (Argon2id algorithm), which is the current OWASP and NIST recommendation for new systems.
  • 2If argon2 is not available, use bcrypt with a work factor of at least 12 or hashlib.scrypt() from the Python standard library.
  • 3Never use bare MD5, SHA-1, SHA-256, or any general-purpose hash function for password storage, even with a salt.
  • 4Implement a migration path for existing MD5 password hashes: rehash with a secure algorithm when users next authenticate.
  • 5Ensure each password has a unique random salt (all three recommended libraries handle this automatically).

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

This rule detects hashlib.md5() calls in contexts that suggest password hashing usage, such as proximity to variables named password, passwd, pwd, credential, or auth, and function names containing these terms. The rule is intentionally broad to catch all patterns where MD5 is applied to credentials.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

NIST SP 800-63B
Section 5.1.1.2: Use a suitable one-way key derivation function (Argon2, bcrypt, scrypt, PBKDF2)
OWASP Top 10
A02:2021 - Cryptographic Failures
PCI DSS v4.0
Requirement 8.3.2: Passwords protected using strong cryptography
GDPR Article 32
Appropriate technical measures including pseudonymisation and encryption of personal data

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about MD5 Used for Password Hashing

No. A salt prevents rainbow table attacks but does not fix the core problem: MD5 is too fast. With a unique salt per user, an attacker must crack each hash individually, but at billions of hashes per second on GPUs, even complex passwords are crackable in hours. A proper password hashing function like argon2 is designed to be thousands of times slower and memory-intensive to prevent this.
General-purpose hash functions (MD5, SHA-256) are designed to be fast for tasks like file integrity checking. Password hashing functions (argon2, bcrypt, scrypt) are designed to be slow and memory-intensive, making brute-force attacks impractical. The deliberate slowness is a feature, not a bug — use a password hashing function whenever storing credentials.
For new systems: Argon2id (OWASP and NIST recommended). For systems where Argon2 is unavailable: bcrypt with rounds >= 12. For standard library only: hashlib.scrypt() with appropriate parameters (n=16384, r=8, p=1 minimum). Never PBKDF2-MD5; use PBKDF2-SHA256 if PBKDF2 is required by compliance, with at least 310,000 iterations.
Use a rehashing strategy: when a user logs in with the old MD5 hash successfully, immediately rehash their password with argon2 and store the new hash. Mark old hashes as needing migration. After a transition period, force-reset passwords for users who haven't logged in. Never store both hashes simultaneously in the same field.
The rule detects contextual indicators that MD5 is being used for passwords. It may miss cases where MD5 is applied to passwords through multiple variable assignments without clear naming conventions. Supplement with a manual code review of all authentication and user registration code paths.
For bcrypt: use at least rounds=12. For Argon2id: OWASP recommends m=19456 KB memory, t=2 iterations, p=1 parallelism as a minimum. Tune the work factor so that hashing takes 0.5-1 second on your target hardware. Re-evaluate the work factor every few years as hardware improves.

New feature

Get these findings posted directly on your GitHub pull requests

The MD5 Used for Password Hashing rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works