Skip to content

fix(web): trade only codes sent back to locallibrary on this computer - #290

Merged
bnb merged 1 commit into
mainfrom
bnb/token-exchange-loopback
Oct 29, 2026
Merged

bnb merged 1 commit into
mainfrom
bnb/token-exchange-loopback

Conversation

@botandbang

Copy link
Copy Markdown
Contributor

What and why

The token exchange accepted any redirect_uri. Mixcloud compares a code's redirect only with the authorize request's, not with one registered for the client, and has no PKCE. So someone could send a Mixcloud sign-in link with Local Network's client and their own redirect. The person signing in sees "Local Network" and approves, and the code goes to that redirect. The exchange would then trade it for that person's Mixcloud token.

Changed: a grant's redirect_uri must be exactly http://127.0.0.1:<port>/callback or http://[::1]:<port>/callback, the only ones locallibrary sends (callback.rs). Anything else is a 400 invalid_request before the service is contacted, and the redirect isn't logged. That applies to code grants, and to refresh grants that carry one. The file's header comment and apps/web/README.md say so.

How it was tested

  • exchange.test.ts: both loopback forms are traded; 12 bad redirects (https, localhost, no port, another path, a query, userinfo, 127.0.0.1.attacker.example, other spellings of the address) are refused for Mixcloud and SoundCloud, with nothing sent upstream and the redirect absent from logs; a refresh with a foreign redirect is refused, and one without a redirect still works. The check was broken four ways and each failed the tests.
  • Locally: format:check, lint, check, knip, test (736) and test:coverage (924 passed, thresholds met; exchange.ts 100% lines and functions, 97.82% branches).

Checklist

  • Tests cover the change
  • The READMEs, docs/ and --help still say what the code does

The token exchange took any redirect_uri. Mixcloud checks a code's redirect only
against the authorize request's, and has no PKCE, so a sign-in link with Local
Network's client and someone else's redirect handed them a code the exchange would
trade for the signed-in person's token. A grant's redirect_uri now has to be
http://127.0.0.1:<port>/callback or http://[::1]:<port>/callback, the only ones
locallibrary sends, and anything else is refused before it reaches the service.
@botandbang
botandbang requested a review from bnb as a code owner October 29, 2026 18:46
@github-actions github-actions Bot added documentation Improvements or additions to documentation web The Local Network website (apps/web) tests Tests, fixtures and test harnesses labels Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Coverage Report for apps/web

Status Category Percentage Covered / Total
🟢 Lines 94.63% (🎯 93%)
🟰 ±0 pp
6038 / 6380
🟢 Statements 92.97% (🎯 91%)
🟰 ±0 pp
9290 / 9992
🟢 Functions 93.58% (🎯 92%)
🟰 ±0 pp
2364 / 2526
🟢 Branches 83.06% (🎯 80%)
⬆️ +0.02 pp
4351 / 5238
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/web/src/lib/server/token-exchange/exchange.ts 100%
🟰 ±0 pp
97.82%
⬆️ +0.46 pp
100%
🟰 ±0 pp
100%
🟰 ±0 pp
Generated in workflow #543 for commit 9005bf2 by the Vitest Coverage Report Action

Size

Compared with main. KiB are 1,024 bytes.

This pull request main Change
Client JavaScript 620.4 KiB 620.4 KiB 0 B (0%)
Client JavaScript, brotli 204.8 KiB 204.8 KiB 0 B (0%)
Client CSS 87.8 KiB 87.8 KiB 0 B (0%)
Client CSS, brotli 12.6 KiB 12.6 KiB 0 B (0%)

@bnb
bnb merged commit bb7a5c6 into main Oct 29, 2026
50 checks passed
@bnb
bnb deleted the bnb/token-exchange-loopback branch October 29, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation tests Tests, fixtures and test harnesses web The Local Network website (apps/web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants