Cryptographic Hash Functions
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep, psalm, and phpstan — these are specialist SAST/static-analysis tools, not default linters. They can flag md5()/sha1() for security use and missing HMAC patterns, but won't catch these issues without deliberate configuration and adoption of those tools.
Closest to 'simple parameterised fix' (e3). The quick_fix describes choosing the right function for the use case: swap md5() for SHA-256, wrap bare hashes in hash_hmac(), replace custom hashing with password_hash(). Each fix is a targeted function-level substitution, typically within a single file or component, not a cross-cutting architectural change.
Closest to 'localised tax' (b3). The misuse affects whichever component handles hashing (password storage, file checksums, message authentication), but doesn't structurally reshape the entire codebase. Once corrected in the relevant module, the rest of the system is largely unaffected. The applies_to scope covers web/cli/queue but the actual hashing logic is usually concentrated in a few locations.
Closest to 'serious trap' (t7). The misconception field captures the canonical wrong belief: SHA-256 looks like a strong, modern cryptographic hash and a competent developer naturally assumes it is suitable for passwords — but it is precisely its speed (billions of ops/second on a GPU) that makes it catastrophically wrong for that use case. This contradicts intuition from general crypto knowledge, where 'stronger/newer' implies 'better for all uses'. The timing-attack trap (== vs hash_equals()) compounds this, making t7 appropriate.
Also Known As
TL;DR
Explanation
Cryptographic hash functions must be: deterministic (same input = same output), fast to compute, pre-image resistant (cannot reverse), second pre-image resistant (cannot find collision for a given input), and collision resistant (cannot find any two inputs with the same hash). SHA-256/SHA-512 (SHA-2 family): widely deployed, no known practical attacks. SHA-3 (Keccak): different construction, quantum-resistant design. BLAKE3: fast, secure, modern. MD5 and SHA-1: broken collision resistance — do not use for security. In PHP: hash('sha256', $data), hash('sha3-256', $data).
Common Misconception
Why It Matters
Common Mistakes
- MD5 for file integrity checksums — collisions have been demonstrated; use SHA-256.
- SHA-256 for password hashing — fast algorithm; use password_hash() with Argon2id.
- Not using HMAC for message authentication — a bare hash can be length-extended; use hash_hmac().
- Comparing hashes with == instead of hash_equals() — timing attack vulnerability.
Code Examples
// MD5 for integrity — broken:
$checksum = md5_file($uploadedFile); // Collisions possible
// SHA-256 for password — wrong tool:
$hash = hash('sha256', $password); // Fast = GPU crackable
// Timing-vulnerable comparison:
if ($computed === $provided) { /* vulnerable to timing attack */ }
// SHA-256 for file integrity:
$checksum = hash_file('sha256', $uploadedFile); // Secure for integrity
// Argon2id for passwords:
$hash = password_hash($password, PASSWORD_ARGON2ID);
// HMAC for message authentication:
$mac = hash_hmac('sha256', $message, $secretKey);
// Constant-time comparison:
if (hash_equals($expected, $computed)) { /* safe */ }