Skip to content

v0.51.3

Choose a tag to compare

@toolhive-release-app toolhive-release-app released this 26 Sep 21:33
· 12 commits to main since this release
88bb284

Security

Embedded authorization server: upstream callback bound to the initiating browser (GHSA-2gjv-f568-6cxp, High)

/oauth/callback completed a login for whichever browser arrived with a valid upstream state. An attacker who started an authorization for their own client could hand the upstream identity provider URL to a victim and receive an authorization code minted for the victim's identity. The device flow's verification-page login shared the same gap.

Both flows now bind the login to the browser that started it: /oauth/authorize and POST /oauth/device set a per-flow cookie whose hash is stored on the pending record, and the callback completes only when the same browser presents it. The device verification form additionally requires an anti-forgery token, so a cross-site page cannot start a device login from a victim's browser.

What changes for operators and tooling

  • Interactive sign-in must be completed in the browser that opened /oauth/authorize or the device verification page, with cookies enabled for that host. Headless drivers that walk the flow with a plain HTTP client must carry cookies between steps, and must load the device verification form before posting a user_code.
  • The upstream callback (redirect_uri, defaulting to {resourceUrl}/oauth/callback in the operator) must share a hostname with the browser-facing authorize URL (authorizationEndpointBaseUrl, else issuer). If the authorize URL is https, a non-loopback callback must be https too. Mismatched deployments log a WARN at startup naming the upstream, and every browser login through it is rejected until fixed.
  • When authorizationEndpointBaseUrl is set, the device flow's verification_uri is now advertised from that base URL instead of the issuer.
  • During a rolling upgrade, a login started on a v0.51.2 replica and finished on v0.51.3 fails within the 10-minute pending window and must be restarted; one started on v0.51.3 and finished on v0.51.2 is not checked.

What's Changed

Full Changelog: v0.51.2...v0.51.3