Hello Simon,
On 02/10/2026 19:41, Simon Quigley wrote:
I claimed ruby-oauth2 in dla-needed.txt. Bookworm has 1.4.4-1, which
still sends a bearer token to the host named by a redirect Location.
That is CVE-2026-54603 (GHSA-pp92-crg2-gfv9). Unstable is fixed in
2.0.25-1 (upstream 2.0.22, commit 0f0a474). Trixie is a different
upstream, 2.0.9, and that fix is a point release rather than this
backport. The debdiff against 1.4.4-1 is attached.
1.4.4's Client#request hands the Location string to Faraday 1.1, and
that turns a protocol-relative Location (//other-host/...) into a new
host while keeping Authorization. The patch resolves that form as a
same-origin path, and drops Authorization when the redirect changes
scheme, host, or port. A same-origin redirect is unchanged. The spec
examples from 0f0a474 are in the patch. One stub is a regexp, because
Faraday 1.1 collapses a triple-slash path when the stub is registered
and then looks the request up uncollapsed.
I ran a local script against the archive package and against this build,
on Bookworm's Ruby 3.1 and Faraday 1.1. The archive package sends the
token to the host in Location, both for the protocol-relative redirect
and for an absolute cross-origin one. This package keeps the protocol-
relative request on the original host, removes the token from the
absolute redirect, and a normal AccessToken#get and client.request still
return the body I expected.
The upstream rspec suite is still disabled, same as 1.4.4-1. spec/
helper.rb needs silent-stream, which Bookworm does not ship, so
autopkgtest's gem2deb-test-runner skips with no test suite. I ran the
redirect examples from the patched spec: 10 examples, 0 failures. The
rest of the suite passes aside from the OAUTH_DEBUG example, which calls
a helper from that missing gem.
Bookworm has two packages that depend on ruby-oauth2: ruby-asana and
ruby-omniauth-oauth2. The OmniAuth providers in Bookworm (GitHub,
GitLab, WordPress, AliCloud, Azure AD, Authentiq, Atlassian, and
DingTalk) depend on ruby-omniauth-oauth2, and they get a token through
that strategy. Asana's ordinary API calls follow redirects in Faraday,
not in OAuth2::Client. The token exchange does go through
Client#request, and so does OmniAuth's auth_code.get_token. DingTalk
also subclasses OAuth2::Client and calls request() itself.
I tested those reverse dependencies against 1.4.4-1+deb12u1. Asana's
authorize URL is still on app.asana.com, a same-origin token redirect
still comes back with a token, and a protocol-relative token redirect
stays on app.asana.com. A client built the way the GitHub strategy
builds one does the same. DingTalk's subclass keeps the request, and its
Authorization header, on oapi.dingtalk.com. A basic_auth token request,
which none of these packages turn on, still follows an absolute cross-
origin redirect and drops Authorization. On 1.4.4-1 the protocol-
relative calls left the provider, and that basic_auth header went with
them. Same-origin redirects and the authorize URLs behaved the same on
both packages.
I built this in a Bookworm LXD container. You can find a Debusine work
request here: https://debusine.debian.net/debian/developers/work-
request/1408442/
Feedback is welcome. If nothing showstopping is raised, I plan on
uploading this to bookworm-security and issuing the DLA on Monday
afternoon (October 5th, 2026).
This looks very good.
In the LTS Team, we'd wait until the trixie SPU is approved
(https://bugs.debian.org/1149723 , even if not published yet), but since
you maintain the package, you can go ahead if you want.
Please also tag debian/1.4.4-1+deb12u1 (gbp tag) at
https://salsa.debian.org/ruby-team/ruby-oauth2/ on upload :)
Cheers!
Sylvain Beucler
Debian LTS Team