diff options
| author | Adam Soltys <[email protected]> | 2026-10-29 16:40:23 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-29 16:40:36 -0700 |
| commit | 9c7d26e0312b7e133801fe9a512e31908c2b29da (patch) | |
| tree | afc64ce611351c9cd22b05c832cfc6ffbfa24770 | |
| parent | 772e4470c599c2992a88031b16e1f05c718f0f05 (diff) | |
| download | coinos-server-9c7d26e0312b7e133801fe9a512e31908c2b29da.tar.gz coinos-server-9c7d26e0312b7e133801fe9a512e31908c2b29da.zip | |
The app pubkey names both the app record and its payment list, so a
non-key value could point a connection at another account's payments.
Reject anything but a 64-character hex key on create and lookup, and
trim the user attached to each payment to the public profile fields.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | routes/users.ts | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/routes/users.ts b/routes/users.ts index 8d902987..e8fdddd5 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -1264,6 +1264,8 @@ export default { async app(req, res) { const { pubkey } = req.params; const { user } = req; + if (!/^[0-9a-f]{64}$/.test(pubkey)) + return res.code(404).send({ error: "connection not found" }); const app = await g(`app:${pubkey}`); // Missing records must 404, not crash into a 500: clients (Damus one-click // setup) probe this endpoint and treat 404 as "not configured yet, create @@ -1278,7 +1280,7 @@ export default { const payments = await Promise.all( pids.map(async (pid) => { const p = await gf(`payment:${pid}`); - if (p) p.user = await g(`user:${p.uid}`); + if (p) p.user = pick((await g(`user:${p.uid}`)) || {}, fields); return p; }), ); @@ -1341,6 +1343,11 @@ export default { const uid = user.id; if (secret) pubkey = getPublicKey(hexToBytes(secret)); + // The pubkey names `app:<pubkey>` and `<pubkey>:payments`, so it must be + // a real NWC key: a user id here would hand the caller that user's + // payment list through GET /app. + if (!/^[0-9a-f]{64}$/.test(pubkey)) fail("Invalid pubkey"); + // App records live under `app:<pubkey>`. Looking up the bare pubkey made // this ownership check ineffective for normal NWC keys and allowed an // authenticated user to overwrite another connection's configuration. |
