Four Hours of Any Password — Python Bug Hunt

Modelled on Dropbox, June 2011: a code update introduced a bug in Dropbox's authentication, and for about four hours accounts could be signed into with any…

  • Language: Python
  • Layer: Backend
  • Difficulty: Easy
  • Concepts: Auth, Security
  • Modelled on: Dropbox · 2011
  • Visible tests: the right password signs in; a wrong password is refused
  • Reward: 50 XP for a complete fix

Briefing

Modelled on Dropbox, June 2011: a code update introduced a bug in Dropbox's authentication, and for about four hours accounts could be signed into with any password. Dropbox found and fixed it the same day and ended the sessions that were opened during the window.

In this reconstruction, the password checker was refactored to return a verdict object (so failures could be logged with a reason) — and the login code kept testing it as if it were a boolean.

Fix login so a wrong password is refused again.

Bug report

BUG-DBX-0619 · Priority: Critical (auth bypass) · Reported by: on-call

login(accounts, username, password) returns a session id or None:

  • "sess-" + username only when the account exists and hashing.verify(...) says the password matches (Verdict.ok is True)
  • an unknown username, an empty password or a non-matching password returns None

Observed: since the verifier refactor every non-empty password signs in.

Logs

[auth] verify user=alice verdict=mismatch -> session sess-alice issued
[auth] 100% of failed verifications resulted in a session in the last 4h

The code as shipped

src/auth/sessions.py (editable)

hashing = bug_require("./hashing.py")


def login(accounts, username, password):
    record = accounts.get(username)
    if record is None:
        return None
    if not password:
        return None
    if hashing.verify(record, password):
        return "sess-" + username
    return None

Read-only context: src/auth/hashing.py.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Python bug hunts.