CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-54603

CVE-2026-54603: Cross-Origin Credential Leakage and SSRF via Protocol-Relative Redirects in ruby-oauth2

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 28, 2026·7 min read·6 visits

Executive Summary (TL;DR)

The oauth2 Ruby gem leaks active Authorization bearer tokens to untrusted external hosts when following protocol-relative redirects (starting with //) and enables server-side request forgery.

An issue in the ruby-oauth2 gem allows unauthenticated attackers to steal OAuth access tokens or perform Server-Side Request Forgery (SSRF) via a protocol-relative URI in HTTP Location redirect headers.

Vulnerability Overview

The oauth2 Ruby gem is an open-source library that implements a client wrapper for the OAuth 2.0 authorization framework. It is widely integrated into Ruby on Rails and other Rack-based web applications to handle identity verification, Single Sign-On (SSO), and API resource consumption. The library interacts with Identity Providers (IdPs) and authorization servers, managing access tokens on behalf of users.

Historically, standard compliance updates introduced support for relative URI redirects within the gem's network request cycle. However, this implementation introduced a critical security flaw: during the handling of standard 3xx redirect status codes (301, 302, 303, and 307), the client fails to securely handle protocol-relative URIs received in the HTTP Location response header.

When a protocol-relative URI (one starting with double slashes, such as //attacker.example) is processed, it completely overrides the original target host and port while keeping the original request options intact. Consequently, the client recursively transmits the active bearer credential to the newly parsed host. This flaw corresponds to CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor) and CWE-601 (URL Redirection to Untrusted Site), yielding a high-severity risk.

Root Cause Analysis

The root cause of this vulnerability lies in the unsafe interaction between HTTP redirection logic and Ruby's standard library URI merging utility (URI#merge). In the vulnerable versions of the library, the redirection handler dynamically extracts the Location header from a 3xx HTTP response. It then resolves the redirection destination by calling response.response.env.url.merge(location), where env.url represents the absolute URI of the original request.

According to the URI standard specified in RFC 3986, a string starting with two forward slashes (//) represents a network-path reference. This format inherits the active URI scheme but indicates a complete replacement of the authority component (the domain and port). When URI#merge combines the base absolute URL https://trusted-idp.example/oauth/token with the protocol-relative input //attacker-controlled.example/steal, the resolved URL evaluates directly to https://attacker-controlled.example/steal.

Furthermore, the client library recursively calls OAuth2::Client#request using the newly computed redirect target URL. Crucially, the local variable req_opts—which contains the HTTP request configurations and headers—is passed directly into the recursive call without validation or modifications. Since the original request parameters contained an Authorization header containing the user's active bearer access token, the client sends this high-privilege token to the attacker-controlled server.

Code Analysis

To understand the flaw at the source-code level, consider the original request loop within lib/oauth2/client.rb in version 2.0.21:

def request(verb, url, req_opts = {}, &block)
  response = execute_request(verb, url, req_opts, &block)
  status = response.status
 
  case status
  when 301, 302, 303, 307
    req_opts[:redirect_count] ||= 0
    req_opts[:redirect_count] += 1
    return response if req_opts[:redirect_count] > options[:max_redirects]
 
    if status == 303
      verb = :get
      req_opts.delete(:body)
    end
    location = response.headers["location"]
    if location
      # Vulnerability: protocol-relative URI replaces authority component
      full_location = response.response.env.url.merge(location)
      # Vulnerability: req_opts passed unmodified, including Authorization headers
      request(verb, full_location, req_opts)
    end
  end
end

To remediate this, the patched version 2.0.22 intercepts protocol-relative URIs and sanitizes the outgoing headers before initiating recursion. The fix modifies the redirect flow to call resolve_redirect_location and sanitize_redirect_options:

# The patched request execution logic
if location
  current_location = response.response.env.url
  # Step 1: Prevent authority hijacking by prefixing relative URLs
  full_location = resolve_redirect_location(current_location, location)
  # Step 2: Strip sensitive headers during cross-origin shifts
  request(verb, full_location, sanitize_redirect_options(req_opts, current_location, full_location))
end

Additionally, the patch implements three helper methods to enforce boundary limits. The resolve_redirect_location helper checks if the target location string starts with //. If so, it prepends ./ to neutralize the authority replacement, converting the string into a relative-path component on the same origin. The sanitize_redirect_options helper checks if a cross-origin redirect occurred using cross_origin_redirect? and purges any keys matching Authorization (case-insensitively) from the request options hash.

Exploitation Methodology

An attacker can exploit this vulnerability through multiple vectors, provided they can influence the destination of an HTTP request executed by the victim application's OAuth client. In a standard enterprise scenario, an attacker identifies an Open Redirect vulnerability on the target Identity Provider (IdP) server. During authentication, the OAuth client calls a token exchange or user-profile endpoint, and the compromised or open-redirecting IdP responds with an HTTP 302 containing Location: //attacker.example/log.

Alternatively, in multi-tenant SaaS environments, tenant administrators can configure custom OIDC metadata endpoints. An attacker can set up a rogue IdP and configure the application to use it as the trusted OAuth authority. When the application's backend queries the malicious metadata or token endpoint, the rogue server returns a protocol-relative redirect targeting the administrative API or internal network addresses.

Below is a sequence diagram illustrating the transaction and subsequent credential disclosure:

Because the browser is not involved in back-channel API calls, no user interaction is required to trigger the final request. Once the server-side application resolves the redirect, the bearer token is sent directly to the adversary-controlled web server. The attacker-controlled server parses the incoming Authorization header and logs the stolen token for persistent API access.

Impact and Security Assessment

The impact of CVE-2026-54603 is significant, representing a high-probability vector for complete credential compromise. The exposure of active access tokens allows attackers to bypass multi-factor authentication (MFA) and access control lists, enabling unauthorized data access or session hijacking on downstream systems. This behavior results in a CVSS v3.1 score of 8.6, emphasizing the critical nature of the flaw.

In addition to credential theft, this vulnerability represents a Server-Side Request Forgery (SSRF) hazard. If an attacker controls the endpoint or redirects the outbound connection, they can force the application server to make arbitrary requests to local network interfaces, metadata endpoints, or database APIs. Because the target URI undergoes standard resolution, local system paths (e.g., //127.0.0.1 or //169.254.169.254) can be accessed blindly through the redirection loop.

The scope of the vulnerability is further broadened by its presence in all versions of the oauth2 library ranging from 0.4.0 to 2.0.21, representing years of production releases. Due to the gem's widespread use as a foundational dependency in OmniAuth strategies and enterprise single-sign-on systems, the potential attack surface spans thousands of internet-exposed applications.

Remediation and Mitigation Strategies

The recommended remediation path is to upgrade the oauth2 dependency to version 2.0.22 or later. This release enforces validation rules that block relative-authority hijacking and strip authentication headers during cross-origin transitions. Teams should inspect their dependency trees via Gemfile.lock to ensure all transitive dependencies (e.g., specific OmniAuth provider plugins) inherit the patched version.

When direct upgrades are blocked by legacy environment dependencies, a monkey-patch must be loaded during the application bootstrap process. This patch overrides the request loop in OAuth2::Client to manually intercept // relative redirects and purge the Authorization header when a cross-origin boundary is traversed. Applying structural monkey-patches provides immediate defense-in-depth without modifying base infrastructure.

Additionally, network-level and application-level controls should be configured to restrict outbound HTTP requests originating from backend application servers. Restricting server egress connections to designated Identity Providers using firewall egress policies prevents connections to unknown domains. Developers should also verify that Identity Provider endpoint configurations are read-only and cannot be manipulated by untrusted administrative accounts.

Official Patches

ruby-oauthOfficial Fix Commit
ruby-oauthv2.0.22 Release Tag

Fix Analysis (1)

Technical Appendix

CVSS Score
8.6/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
12,000
via Censys/Shodan estimate for ruby-based oauth2 clients

Affected Systems

Ruby applications using the oauth2 gem for OAuth authentication workflows

Affected Versions Detail

Product
Affected Versions
Fixed Version
oauth2
ruby-oauth
>= 0.4.0, <= 2.0.212.0.22
AttributeDetail
CWE IDCWE-200, CWE-601
Attack VectorNetwork (AV:N)
CVSS v3.1 Score8.6 (High)
EPSS ScoreNot Available
ImpactHigh (Credential Disclosure / SSRF)
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1552Unsecured Credentials
Credential Access
T1005Data from Local System
Collection
T1566.002Spearphishing Link
Initial Access
CWE-200
Exposure of Sensitive Information to an Unauthorized Actor

The product exposes sensitive information to an actor who is not authorized to have access to that information.

Vulnerability Timeline

Relative location redirection support introduced
2022-02-21
Vulnerability reported, fixed, and v2.0.22 released
2026-06-07
Public security advisory published (GHSA-pp92-crg2-gfv9)
2026-07-28

References & Sources

  • [1]GitHub Security Advisory
  • [2]NVD CVE-2026-54603

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•10 minutes ago•GHSA-XVG2-CGV6-6H7V
7.4

GHSA-XVG2-CGV6-6H7V: Local Traffic Interception and Information Disclosure via Improper DNS Block Responses in netfoil

A protection mechanism failure in the netfoil DNS proxy prior to version 0.4.0 causes blocked domains to resolve to null IP addresses (0.0.0.0 or ::) with a NOERROR status instead of NXDOMAIN. On Linux systems, connections to these addresses are routed to the loopback interface (localhost), allowing local processes to intercept sensitive HTTP traffic, including authorization headers and session cookies, intended for the blocked domains.

Amit Schendel
Amit Schendel
0 views•6 min read
•about 1 hour ago•GHSA-PMWX-RM49-XV39
9.1

GHSA-PMWX-RM49-XV39: Path Traversal in ActiveRecord::Tenanted::Storage::DiskService

A directory traversal vulnerability exists in the `activerecord-tenanted` Ruby gem's local storage path resolution logic. Prior to version 0.7.0, the `path_for` method failed to sanitize input keys, allowing remote attackers to traverse directories and access arbitrary files on the host filesystem.

Alon Barad
Alon Barad
2 views•6 min read
•about 2 hours ago•CVE-2026-54712
5.3

CVE-2026-54712: Uncontrolled Resource Consumption in OpenTelemetry Javaagent RMI Context Propagation

An uncontrolled resource consumption vulnerability in the OpenTelemetry Javaagent RMI context propagation mechanism allows remote unauthenticated attackers to cause a Denial of Service (DoS) via heap memory exhaustion.

Alon Barad
Alon Barad
2 views•7 min read
•about 3 hours ago•CVE-2026-54704
6.5

CVE-2026-54704: Sensitive Data Exposure in OpenTelemetry Java Instrumentation SQL Sanitizer

A sensitive data exposure vulnerability (CWE-532) exists in OpenTelemetry Java Instrumentation prior to version 2.28.0. The JDBC auto-instrumentation component's SQL statement sanitizer contains lexer flaws that prevent the correct redaction of administrative passwords under specific conditions, such as when double-quotes represent identifiers or during multi-statement executions separated by semicolons.

Alon Barad
Alon Barad
3 views•5 min read
•about 4 hours ago•CVE-2026-54705
6.3

CVE-2026-54705: DOM-Based Cross-Site Scripting in MathLive LaTeX Rendering Engine

CVE-2026-54705 is a critical DOM-based Cross-Site Scripting (XSS) vulnerability affecting the MathLive library prior to version 0.110.0. The flaw stems from a lack of proper character escaping in the rendering path for LaTeX text-mode commands such as \text{} and \mbox{}, enabling unauthenticated attackers to execute arbitrary JavaScript in the victim's browser.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 5 hours ago•CVE-2026-54693
8.2

CVE-2026-54693: Authorization Bypass in ZITADEL Identity Management Platform

A critical authorization bypass vulnerability was identified in the ZITADEL identity management platform, tracked as CVE-2026-54693 (GHSA-jq8w-8q2f-ffm9). Due to incorrect privilege validation in self-service profile modification endpoints, standard authenticated users could obtain plaintext verification codes during email or phone number updates. This allows attackers to claim and verify arbitrary email addresses or phone numbers without controlling the underlying contact methods.

Alon Barad
Alon Barad
4 views•7 min read