Raised by CodeRabbit during review of #55 (ai-hist coverage). Declined there as out of scope, because fixing it in one function would have made the CLI less consistent, not more. Filing so it isn't lost.
The issue
StoredAuth.base_url can hold an http:// URL, and three call sites send the service-local rth_at_ bearer to it with no scheme validation:
| call site |
file |
UreqIngestor::ingest (push) |
crates/ai-hist/src/cloud.rs:227 |
pair_check |
crates/ai-hist/src/cloud.rs:526 |
fleet_coverage |
crates/ai-hist/src/cloud.rs (added in #55) |
validate_cloud_exchange_base_url (cloud.rs:415) exists but is wired at exactly one site — login_via_cloud (cloud.rs:409). That is deliberate and correct as far as it goes: it guards the Agent Relay Cloud bearer at exchange time. It says nothing about the service-local token afterward.
Why it wasn't fixed in #55
Enforcing HTTPS in fleet_coverage alone would have:
- broken the documented
http://localhost:8787 wrangler dev flow for coverage while push and pair kept working against the same URL, and
- closed none of the actual exposure —
push runs on a 300s timer, so it is the high-frequency path by a wide margin.
A one-command fix would have been visible without being useful.
What a real fix looks like
Validate once, centrally — ideally where StoredAuth is loaded or where the request is built, so all three sites are covered and no future call site can miss it:
- require
https:// by default;
- allow loopback (
127.0.0.1, ::1, localhost) so local wrangler dev keeps working;
- gate any other plaintext host behind an explicit opt-in, mirroring the existing
RELAYHISTORY_ALLOW_UNTRUSTED_CLOUD_BASE_URL precedent rather than inventing a second mechanism.
Worth doing as one deliberate change with tests per call site, not piecemeal.
Severity
Low in practice — the stored base_url is set by the user's own login, so this is a footgun rather than a remote attack. It matters most for a --base-url typo or a dev endpoint left configured on a machine that then runs the push service unattended.
Raised by CodeRabbit during review of #55 (
ai-hist coverage). Declined there as out of scope, because fixing it in one function would have made the CLI less consistent, not more. Filing so it isn't lost.The issue
StoredAuth.base_urlcan hold anhttp://URL, and three call sites send the service-localrth_at_bearer to it with no scheme validation:UreqIngestor::ingest(push)crates/ai-hist/src/cloud.rs:227pair_checkcrates/ai-hist/src/cloud.rs:526fleet_coveragecrates/ai-hist/src/cloud.rs(added in #55)validate_cloud_exchange_base_url(cloud.rs:415) exists but is wired at exactly one site —login_via_cloud(cloud.rs:409). That is deliberate and correct as far as it goes: it guards the Agent Relay Cloud bearer at exchange time. It says nothing about the service-local token afterward.Why it wasn't fixed in #55
Enforcing HTTPS in
fleet_coveragealone would have:http://localhost:8787wrangler devflow forcoveragewhilepushandpairkept working against the same URL, andpushruns on a 300s timer, so it is the high-frequency path by a wide margin.A one-command fix would have been visible without being useful.
What a real fix looks like
Validate once, centrally — ideally where
StoredAuthis loaded or where the request is built, so all three sites are covered and no future call site can miss it:https://by default;127.0.0.1,::1,localhost) so localwrangler devkeeps working;RELAYHISTORY_ALLOW_UNTRUSTED_CLOUD_BASE_URLprecedent rather than inventing a second mechanism.Worth doing as one deliberate change with tests per call site, not piecemeal.
Severity
Low in practice — the stored
base_urlis set by the user's ownlogin, so this is a footgun rather than a remote attack. It matters most for a--base-urltypo or a dev endpoint left configured on a machine that then runs the push service unattended.