aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-07 22:58:52 -0700
committerAdam Soltys <[email protected]>2026-08-07 23:29:24 -0700
commit01784219f83f68c7d03eb19c35f05eeaedc74487 (patch)
treec96a432094da1a655e98bbdf3f90fcf8e1052d61 /routes
parentbc5b34f053cf35c11a68e57a9c43c987331452a7 (diff)
downloadcoinos-server-01784219f83f68c7d03eb19c35f05eeaedc74487.tar.gz
coinos-server-01784219f83f68c7d03eb19c35f05eeaedc74487.zip
sockets: verify JWT signatures on the websocket auth path (S1)
The websocket auth gate used jwt.decode(), which parses the payload but never checks the signature — anyone could forge {id: <victim uid>} (alg:none or any key), register their socket under the victim's uid, and receive every emit for that account. Switch both track() and the "login" gate to jwt.verify(token, config.jwt), rejecting forged/altered tokens. Also project the full-record socket emits through pick(user, whitelist) so a "user" event can never carry the bcrypt hash, TOTP secret, or PIN — matching the shape /login and /me already return. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Diffstat (limited to 'routes')
-rw-r--r--routes/users.ts8
1 files changed, 4 insertions, 4 deletions
diff --git a/routes/users.ts b/routes/users.ts
index 182c43aa..f10b728b 100644
--- a/routes/users.ts
+++ b/routes/users.ts
@@ -204,7 +204,7 @@ export default {
user.twofa = false;
await s(`user:${id}`, user);
- emit(username, "user", user);
+ emit(username, "user", pick(user, whitelist));
emit(username, "otpsecret", user.otpsecret);
l("disabled 2fa", username);
res.send({});
@@ -221,7 +221,7 @@ export default {
if (isValid) {
user.twofa = true;
await s(`user:${id}`, user);
- emit(username, "user", user);
+ emit(username, "user", pick(user, whitelist));
} else {
return res.code(500).send("Invalid token");
}
@@ -365,8 +365,8 @@ export default {
await s(`user:${user.id}`, user);
if (user.nip5) await db.sAdd("nip5", `${user.username}:${user.pubkey}`);
- emit(user.id, "user", user);
- res.send({ user });
+ emit(user.id, "user", pick(user, whitelist));
+ res.send({ user: pick(user, whitelist) });
} catch (e) {
warn("failed to update", user.username, e.message);
bail(res, e.message);