diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-11-06 09:06:36 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-11-06 09:06:36 +0000 |
| commit | ba3ca37897c12d2d285f48e8a429d47b40773df5 (patch) | |
| tree | ba16ffa89482480cc22e22a05fc4f59b0ea90012 /tools | |
| parent | 146400bade723522b7bea117efc1c9cc48469455 (diff) | |
Send the server's token as a header, so the audio URL can stop carrying one
Groundwork for the server to stop putting the token in /audio/ query strings. Apache no longer
writes those to disk, but a secret in a URL still travels through everything that handles the
URL, and the only reason it was there is that the downloader had no credentials of its own.
Now it does: ServerAudio gains bearerFor(url), ServerSkips answers it from the configured
address, and downloadOverHttp attaches Authorization: Bearer when it gets one.
**The whole risk is in that one question.** This downloader also fetches episodes from whatever
CDN a publisher nominates, so an over-eager match would hand Peter's server credentials to every
podcast host he subscribes to -- strictly worse than the leak being closed. ServerBearer
therefore compares parsed origins, scheme and host and port, never the text of the URL, and the
test is mostly near misses: a host the server's name is a prefix of, one it is a suffix of, the
name appearing in a path or a query or a fragment, a userinfo section ending in the server's name
before an `@`, a downgraded scheme, a different port. Several of those pass a naive string match.
One of those tests needed a test of its own. `https://listen.terst.org@evil.example/...` is
refused, but it would also be refused if the URL simply failed to parse -- in which case the
origin check was never reached and the thing I thought I was testing was untested. So there is an
assertion that it parses, with host evil.example and username listen.terst.org.
The wiring test runs the real ServerSkips rather than a fake and checks the publisher path sends
no Authorization at all, because the unit tests above it fake exactly the component whose
host-matching is the safety property.
The server still emits the query token; this has to be installed before that stops, or downloads
401 in the gap. That is the next change, not this one.
1052 tests, detekt 0, lint clean, coverage 94.06% -> 94.09%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'tools')
0 files changed, 0 insertions, 0 deletions
