/** * Pass: weak-password-hash (CWE-916, category: security) * * Detects use of a fast / unsalted hash, or a KDF with insufficient * computational cost, applied to a credential-named identifier. * * Distinct from `weak-hash` (CWE-328): * - `weak-hash` flags broken algorithms (MD2/MD4/MD5/SHA-1) at any call site. * - `weak-password-hash` flags algorithm/cost choices that are SAFE for * general digests but UNSAFE for password storage (e.g. plain SHA-256 * of a password, bcrypt cost < 10, PBKDF2 iterations < 100k). * * Detection per language: * Python: * - `hashlib.sha256(password)` / `.sha512(...)` / etc. where the * argument is a credential-named identifier. * - `bcrypt.hashpw(pw, bcrypt.gensalt(rounds=N))` where N < 10. * - `PBKDF2HMAC(..., iterations=N).derive(pw)` where N < 100000. * JS/TS: * - `crypto.createHash('sha256').update(password).digest()`. * - `bcrypt.hash(pw, N)` / `bcrypt.hashSync(pw, N)` where N < 10. * - `crypto.pbkdf2Sync(pw, salt, N, ...)` where N < 100000. * Java: * - `MessageDigest.getInstance("SHA-256")` followed by `.update(pw)` — * conservative: detect `MessageDigest.getInstance` + `.update(credIdent)` * on any non-broken algorithm. (Broken algos already flagged by weak-hash.) * - `PBEKeySpec(pw, salt, N, ...)` where N < 100000. * Go: * - `sha256.Sum256([]byte(password))`, `sha512.Sum512([]byte(password))`. * - `bcrypt.GenerateFromPassword(pw, cost)` where cost < 10. * * Aligned with: OWASP ASVS 2.4.1, NIST SP 800-63B §5.1.1.2, gosec G401-style. */ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js'; export interface WeakPasswordHashResult { findings: Array<{ line: number; language: string; kind: 'fast-unsalted-hash' | 'low-bcrypt-cost' | 'low-pbkdf2-iterations'; api: string; }>; } export declare class WeakPasswordHashPass implements AnalysisPass { readonly name = "weak-password-hash"; readonly category: "security"; run(ctx: PassContext): WeakPasswordHashResult; private detect; } //# sourceMappingURL=weak-password-hash-pass.d.ts.map