pwneglyph logo
web javascript nodejs authentication-bypass bcrypt async-bug logic-bug

Exploit if (bcrypt.compare(...)) without await — a Promise is truthy, so any password logs in.

Missing await on bcrypt.compare() Makes Auth Always Truthy

A Promise object is truthy. If auth code uses if (bcrypt.compare(...)) instead of await bcrypt.compare(...), the branch succeeds regardless of the password.

Why It Works

  • bcrypt.compare returns a Promise, which is always truthy; without await, the password check never actually runs.

Vulnerable Pattern

  • Async password verification inside an if in JS/TS, especially in rushed Express controller code.

Exploit Flow

  1. Inspect source, stack traces, or decompiled bundles for a missing await.
  2. If source is unavailable, try random passwords and compare behavior to a definitely nonexistent user to isolate the logic bug.

Variations

  • Similar mistakes with argon2.verify, database promises, or Promise<boolean> wrappers around authorization checks.

Common Blockers

  • Transpilation doesn't save you; the only real blocker is the code already awaiting correctly.

PoC Sketch

// vulnerable shape — logs in with any password:
if (bcrypt.compare(password, user.hash)) { login(user); }

Good Situations To Use It

  • A Node/Express login compares passwords with bcrypt/argon2.
  • You suspect a missing await.
  • Any password succeeds for a known user.

Sources

  • plfanzen2026/web/thank_you_javascript