Lab + writeup for CVE-2026-44166: PocketBase OAuth2 account pre-hijacking via unvalidated createData.email
A PocketBase auth collection with OAuth2 enabled lets the client pass a createData object when it signs up. The email inside createData is never checked against the email the OAuth2 provider verified. Anyone with an account on a configured provider can register a record that carries someone else's email, linked to their own OAuth2 identity.
With one provider configured, the real owner is locked out. With two or more, the owner logs in later through a different provider and ends up sharing the account with the attacker.
Affected: < 0.22.42 and >= 0.30.0, < 0.37.4. Fixed in 0.22.42 and 0.37.4.
Advisory: GHSA-pq7p-mc74-g65w. CWE-287. CVSS 4.0 6.1.
Full writeup: WRITEUP.md
python fetch_binaries.py # pulls vulnerable 0.37.3 + patched 0.37.4 for your OS
python poc.py # pre-claim and lockout against the vulnerable build
python verify_fix.py 0.37.4 # same steps on the patched build, attacker gets evicted
Python 3.8+, standard library only. The PoC runs offline against a bundled mock OAuth2 provider, so there is no real IdP or network target.
Vulnerable 0.37.3:
[1] Attacker token issued for: [email protected] (verified=False)
[2] Victim login: HTTP 400 -- Failed to authenticate.
[3] Attacker re-auth: [email protected] -- same record: True
Patched 0.37.4:
[1] Attacker pre-claims: [email protected] verified=False id=...
[2] Victim login: SUCCESS verified=True id=... => victim owns the account
[3] Attacker re-auth: [email protected] id=... same-as-victim=False
| File | Purpose |
|---|---|
WRITEUP.md | Root-cause analysis, both attack variants, remediation, detection |
fetch_binaries.py | Downloads the 0.37.3 / 0.37.4 binaries for your OS/arch |
mock_oauth2_server.py | Small offline mock OAuth2 provider (token + userinfo) |
poc.py | The exploit against the vulnerable build |
verify_fix.py | Runs the same steps on any build and reports the outcome |
For education and authorised security testing: your own lab, CTF and HTB boxes, in-scope bug bounty targets. The lab is offline and never touches anything you don't run yourself.