aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/api
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-01 17:49:13 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-01 17:49:13 +0200
commit7d8c774e250b134222374f45726d5426714475de (patch)
treed5cf7e7df3131dc51c5c46cc0e8c7ffb4aed0240 /packages/meshbay-hub/src/meshbay_hub/api
parent99eb93a00269fbfafba7536cf1613b3d4c18c3ce (diff)
downloadmeshbay-7d8c774e250b134222374f45726d5426714475de.tar.gz
fix(hub): enforce registration captcha for every client
The server only checked the captcha when auth_key was absent — but every real client (browser included, via the password split) sends auth_key, so the check was off for everyone, and a bot skipped it by including the field. The Register form still made humans solve a widget whose token was never transmitted. Gate is now unconditional on captcha.enabled. The web client (registerUser in keyderive.js) forwards captcha.token; RegisterPage resets the (single-use) token on a failed attempt. The desktop client shares this UI source and is Chromium, so it renders the same widget (see the paired meshbay-client commit for the CSP change that allows it). Tests: test_register_captcha.py. Third security review, finding M1 (Option A). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pG75yGK3NthNfyjH74omG
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/api/users.py9
1 files changed, 7 insertions, 2 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/users.py b/packages/meshbay-hub/src/meshbay_hub/api/users.py
index 559cfa6..9b70b59 100644
--- a/packages/meshbay-hub/src/meshbay_hub/api/users.py
+++ b/packages/meshbay-hub/src/meshbay_hub/api/users.py
@@ -150,8 +150,13 @@ async def register(
return {"user_id": found.id, "email_verification_required": True}
raise HTTPException(status_code=409, detail="Username already taken")
- # Captcha gate — web path only (native clients send auth_key)
- if _cfg and _cfg.captcha.enabled and not body.auth_key:
+ # Captcha gate — every fresh registration when a captcha is configured, with
+ # no client carve-out. The earlier `and not body.auth_key` exempted anything
+ # that sent an `auth_key`, which is *every* real client (the browser sends it
+ # too, from the password split) — so the check was off for everyone, and a
+ # bot skipped it by sending the field. The desktop client is Chromium and
+ # renders the same widget, so it has no need of an exemption either.
+ if _cfg and _cfg.captcha.enabled:
await _verify_captcha_or_raise(body.captcha_token, request)
# Email uniqueness (only active or pending accounts)