Skip to content

Commit 9981717

Browse files
jasnowRubySec CI
authored andcommitted
Updated advisory posts against rubysec/ruby-advisory-db@78c05fd
1 parent 389c952 commit 9981717

2 files changed

Lines changed: 184 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
layout: advisory
3+
title: 'GHSA-pp92-crg2-gfv9 (oauth2): Protocol-relative redirect Location overrides
4+
authority in OAuth2::Client#request, leaking bearer Authorization to attacker host'
5+
comments: false
6+
categories:
7+
- oauth2
8+
advisory:
9+
gem: oauth2
10+
ghsa: pp92-crg2-gfv9
11+
url: https://github.com/ruby-oauth/oauth2/security/advisories/GHSA-pp92-crg2-gfv9
12+
title: Protocol-relative redirect Location overrides authority in OAuth2::Client#request,
13+
leaking bearer Authorization to attacker host
14+
date: 2026-06-07
15+
description: |-
16+
## Summary
17+
18+
When an application uses OAuth2::Client (typically via an
19+
OAuth2::AccessToken) and the configured authorization server returns
20+
a redirect whose Location header is a protocol-relative URI of the
21+
form //attacker.example/leak, OAuth2::Client#request resolves the
22+
redirect with response.response.env.url.merge(location). Per
23+
RFC 3986 §5.2, an input that starts with // is a network-path reference
24+
and replaces the authority of the base URL:
25+
URI("http://idp.trusted/userinfo").merge("//attacker.example/leak")
26+
returns http://attacker.example/leak. The recursive request(verb,
27+
full_location, req_opts) call then re-sends the request to the attacker
28+
host while preserving the Authorization: Bearer <access-token> header
29+
that OAuth2::AccessToken#configure_authentication! installed on
30+
req_opts[:headers] for the original request.
31+
32+
The result is a one-shot cross-origin credential disclosure: any 30x
33+
response from the IdP that an attacker can influence (a compromised
34+
endpoint, a tenant-controlled IdP in a multi-tenant deployment, or an
35+
open-redirect handler that does not normalise the Location it emits)
36+
can extract the bearer access token of the calling user.
37+
38+
## Affected
39+
40+
* oauth2 v2.0.21 and all prior versions back to and including v0.4.0.
41+
* The underlying unsafe redirect-following behavior that
42+
reuses headers starts in v0.4.0 via b944da5.
43+
* The vulnerability was retained when the code was refactored
44+
to a redirect helper, and in this form has been present in
45+
OAuth2::Client#request since v2.0.0 via b944da5.
46+
* Ruby 4.0.5 on arm64-darwin25. The behaviour of URI#merge for
47+
protocol-relative inputs is RFC-conformant and the same on every
48+
supported Ruby (≥ 2.x).
49+
* Adapter independence: confirmed against the default faraday 2.14.2 +
50+
faraday-net_http 3.4.3 stack. The URI#merge call is in oauth2
51+
itself, not in Faraday, so the issue is not adapter-specific.
52+
53+
## Impact
54+
55+
A consumer that uses OAuth2::AccessToken#get / #post / #request
56+
against an IdP whose redirect target an attacker can influence (open
57+
redirect, malicious tenant, or in-path adversary) loses two things at once:
58+
59+
1. Cross-origin credential disclosure. The connection-scoped
60+
Authorization: Bearer <token> header attached by
61+
OAuth2::AccessToken#configure_authentication! is sent to the
62+
attacker host on the very next request, with no second user interaction.
63+
2. SSRF from the application server. The OAuth2 client follows the
64+
redirect on behalf of the application, so the host that ultimately
65+
receives the request is one the attacker chooses — useful for
66+
hitting internal addresses (//169.254.169.254/..., //127.0.0.1:.../...)
67+
that the application server can reach but the attacker cannot.
68+
69+
The combined primitive is stronger than the usual cross-origin-redirect
70+
leak because no application-level cooperation is required and no
71+
Location: http://attacker/... is needed — the protocol-relative
72+
//attacker/x form slips past naive scheme-based Location filters
73+
that allow same-scheme-implicit redirects.
74+
75+
## Credit
76+
77+
* Reported by tonghuaroot.
78+
cvss_v3: 8.6
79+
unaffected_versions:
80+
- "< 0.4.0"
81+
patched_versions:
82+
- ">= 2.0.22"
83+
related:
84+
url:
85+
- https://github.com/ruby-oauth/oauth2/blob/v2.0.22/CHANGELOG.md
86+
- https://github.com/ruby-oauth/oauth2/releases/tag/v2.0.22
87+
- https://github.com/ruby-oauth/oauth2/commit/442c1609858ebaecbac5eab77f4511bc81ed7383
88+
- https://github.com/ruby-oauth/oauth2/security/advisories/GHSA-pp92-crg2-gfv9
89+
notes: |
90+
- Not on GHSA.
91+
- No CVE value - will add it if it shows up.
92+
- No NVD/[cvss_v2, cvss_v4] values - v3 from GHSA.
93+
---
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
layout: advisory
3+
title: 'GHSA-prq8-7wvh-44qh (oauth): Cross-origin OAuth token-request redirects can
4+
expose signed request metadata'
5+
comments: false
6+
categories:
7+
- oauth
8+
advisory:
9+
gem: oauth
10+
ghsa: prq8-7wvh-44qh
11+
url: https://github.com/ruby-oauth/oauth/security/advisories/GHSA-prq8-7wvh-44qh
12+
title: Cross-origin OAuth token-request redirects can expose signed request metadata
13+
date: 2026-06-07
14+
description: |-
15+
## Summary
16+
17+
When an application uses OAuth::Consumer to request OAuth 1.0 request
18+
tokens or access tokens, the token request helper follows 300..399
19+
redirects returned by the OAuth server. In affected versions,
20+
OAuth::Consumer#token_request parses the raw Location header, follows
21+
the redirect recursively, and can mutate the consumer's configured
22+
site when the redirect points to a different host with the same path.
23+
24+
The result is a cross-origin signed-request disclosure primitive: if an OAuth
25+
server token endpoint returns a redirect whose target an attacker controls,
26+
the client can re-sign the token request and send OAuth 1.0 request metadata,
27+
including the OAuth signature, nonce, timestamp, consumer key, and any request
28+
parameters included in the signature base string, to the attacker-controlled
29+
host. The same behavior can also be used as an SSRF or confused-deputy
30+
primitive because the application server follows the redirect and sends
31+
the next request from its own network position.
32+
33+
## Affected
34+
35+
oauth v1.1.5 and prior versions back to and including v0.5.5.
36+
The cross-host token redirect behavior was introduced by d74b767f
37+
The behavior is documented in the v0.5.5 changelog as "Allow redirect to
38+
different host but same path".
39+
The vulnerable behavior is in OAuth::Consumer#token_request, which is
40+
used by the documented request-token and access-token flows.
41+
The issue is not specific to a Ruby engine or platform. It is caused by the
42+
gem's redirect handling and recursive token request behavior.
43+
Patched version: oauth v1.1.6.
44+
45+
## Impact
46+
47+
A consumer that calls OAuth::Consumer#get_request_token,
48+
OAuth::Consumer#get_access_token, or lower-level token request helpers
49+
against an OAuth server whose token endpoint redirect target can be
50+
influenced may lose three security properties:
51+
52+
Cross-origin signed-request metadata disclosure. The redirected request is
53+
signed for the attacker-controlled endpoint. Depending on the request method,
54+
scheme, and parameters, the attacker may receive OAuth 1.0 parameters such as
55+
oauth_consumer_key, oauth_signature_method, oauth_timestamp,
56+
oauth_nonce, oauth_version, and oauth_signature.
57+
SSRF from the application server. The OAuth client follows the redirect on
58+
behalf of the application, so the redirected host is contacted from the
59+
application server's network position.
60+
Confused-deputy behavior. A malicious or compromised token endpoint can
61+
cause an otherwise trusted application to initiate signed requests to an
62+
unintended origin.
63+
The disclosed OAuth 1 signature is not equivalent to an OAuth 2 bearer token:
64+
it is bound to the signed request, timestamp, nonce, HTTP method, and request
65+
URL. However, it can still disclose sensitive integration metadata, may be
66+
replayable within the receiver's accepted nonce/timestamp window in some
67+
deployments, and can expose application-server reachability to
68+
attacker-selected hosts.
69+
70+
## Credit
71+
72+
* Found during the follow-up audit for GHSA-pp92-crg2-gfv9.
73+
74+
* Reporter/coordinator: Peter H. Boling (pboling)
75+
cvss_v3: 7.2
76+
unaffected_versions:
77+
- "< 0.5.5"
78+
patched_versions:
79+
- ">= 1.1.6"
80+
related:
81+
url:
82+
- https://github.com/ruby-oauth/oauth/blob/v1.1.6/CHANGELOG.md
83+
- https://github.com/ruby-oauth/oauth/releases/tag/v1.1.6
84+
- https://github.com/ruby-oauth/oauth/commit/d74b767f
85+
- https://github.com/ruby-oauth/oauth/security/advisories/GHSA-pp92-crg2-gfv9
86+
- https://github.com/ruby-oauth/oauth/security/advisories/GHSA-prq8-7wvh-44qh
87+
notes: |
88+
- Not on GHSA.
89+
- No CVE value - will add it if it shows up.
90+
- No NVD/[cvss_v2, cvss_v4] values - v3 from GHSA.
91+
---

0 commit comments

Comments
 (0)