← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Rainbow Table

General PHP 5.5+ Intermediate
debt(d5/e3/b5/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), semgrep rules can flag md5($password)/sha1($password) patterns without salt, but unsalted hashing won't show up in default linting.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), swapping md5/sha1 to password_hash() is straightforward in code but requires a migration path for existing stored hashes (rehash on next login), which is more than a one-liner.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5), password storage is load-bearing across auth flows (registration, login, reset) — picking the wrong scheme shapes every auth touchpoint until migrated.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5), the misconception that long passwords or a single app-wide salt defeats rainbow tables is a documented gotcha — devs assume hashing alone is safe when per-user salts are the actual defence.

About DEBT scoring →

Also Known As

rainbow table attack precomputed hash table hash lookup table

TL;DR

A precomputed lookup table mapping hash values back to their original inputs — used to crack unsalted password hashes.

Explanation

Rainbow tables trade disk space for cracking speed. Attackers precompute hashes of millions of common passwords and look up a stolen hash in the table to instantly recover the original password. Salting defeats rainbow tables by ensuring the same password produces a different hash each time — so a rainbow table would need to be computed separately for every possible salt. password_hash() salts automatically. Unsalted MD5/SHA1 hashes of common passwords are crackable in milliseconds.

Common Misconception

Long passwords are immune to rainbow table attacks. Rainbow tables can cover long passwords for limited character sets. Per-user salts defeat rainbow tables entirely by making precomputation infeasible — salting is the canonical defence, not password length alone.

Why It Matters

Rainbow tables are precomputed hash-to-plaintext lookups — an unsalted hash of 'password123' is looked up instantly in a rainbow table, which is why per-password unique salts are essential.

Common Mistakes

  • Storing unsalted MD5 or SHA1 password hashes — rainbow tables crack them in milliseconds.
  • Using a single application-wide salt — rainbow tables can be precomputed for that specific salt.
  • Using salted hashes but fast algorithms (MD5, SHA256) — salts defeat rainbow tables but not GPU brute force; use bcrypt/argon2.
  • Not using password_hash() which handles salting automatically with a secure algorithm.

Code Examples

✗ Vulnerable
// Unsalted MD5 — rainbow table cracks instantly:
$hash = md5($password); // 'password123' → '482c811da5d5b4bc6d497ffa98491e38'
// This exact hash appears in every rainbow table

// Correct — password_hash() adds unique salt automatically:
$hash = password_hash($password, PASSWORD_ARGON2ID);
✓ Fixed
// Rainbow tables: precomputed hash → password mappings
// Defeated by per-password salts

// Bad — unsalted hash is rainbow-table vulnerable:
$hash = md5($password);       // rainbow table cracks this instantly
$hash = sha1($password);      // same problem

// Good — password_hash() automatically generates and stores a unique salt:
$hash = password_hash($password, PASSWORD_ARGON2ID);
// Hash includes: algorithm, cost, salt, and digest — all in one string
// $argon2id$v=19$m=65536,t=4,p=1\$[22-char-salt]\$[43-char-hash]

// Even if the DB is leaked:
// Each password has a unique salt → no precomputed table helps
// Argon2id's memory-hard algorithm → GPU cracking is expensive

Added 15 Mar 2026
Edited 22 Mar 2026
Views 121
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping M 0 pings T 1 ping W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 2 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T
No pings yet today
Google 1
Amazonbot 19 Perplexity 14 Google 8 Scrapy 8 Ahrefs 7 ChatGPT 6 SEMrush 6 PetalBot 6 Unknown AI 2 Bing 2 Brave Search 2 Applebot 2 Meta AI 1 Sogou 1 Twitter/X 1
crawler 83 crawler_json 2
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Use password_hash() which adds a unique random salt automatically — salted hashes defeat rainbow tables because each hash is unique even for identical passwords
📦 Applies To
PHP 5.5+ web cli
🔗 Prerequisites
🔍 Detection Hints
Unsalted hash: md5($password) sha1($password) without unique per-user salt
Auto-detectable: ✓ Yes semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line Tests: Update
CWE-759 CWE-916


✓ schema.org compliant