Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-70665

CVE-2026-70665: Doorkeeper OpenID Connect Privilege Escalation

CVE-2026-70665 is a privilege escalation vulnerability in Doorkeeper OpenID Connect that allows self-registered clients to obtain unauthorized scopes. This post covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-70665 Overview

CVE-2026-70665 is an authorization flaw [CWE-285] in the Doorkeeper OpenID Connect gem, which implements an OpenID Connect (OIDC) authentication provider for Ruby on Rails applications on top of Doorkeeper. Versions prior to 1.10.4 fail to validate client-supplied scopes at the Dynamic Client Registration (DCR) endpoint. A self-registered client can persist scopes beyond the server's configured scope set, creating a privilege escalation path against protected OAuth resources.

Critical Impact

A remote attacker able to register a client through the DCR endpoint can request and be granted OAuth scopes the server never intended to expose, undermining access control on downstream APIs.

Affected Products

  • Doorkeeper OpenID Connect gem versions prior to 1.10.4
  • Rails applications using Doorkeeper with Dynamic Client Registration enabled
  • Deployments relying on default configuration where enforce_configured_scopes is off

Discovery Timeline

  • 2026-08-25 - CVE-2026-70665 published to the National Vulnerability Database
  • 2026-08-25 - Last updated in NVD database

Technical Details for CVE-2026-70665

Vulnerability Analysis

The flaw resides in DynamicClientRegistrationController#application_params, where the scopes attribute of a new client is assigned directly from params[:scope] without validation. The controller trusts client-supplied metadata during registration and persists it to the application record.

Doorkeeper's ScopeChecker prioritizes application-level scopes over server-level scopes when evaluating token requests. When enforce_configured_scopes is left at its default (off) value, a scope stored on the registered application is treated as authoritative. A client can register with arbitrary scope strings and later request access tokens bearing those scopes.

The vulnerability requires an unauthenticated network-reachable DCR endpoint and specific configuration conditions, which limits exploitability but still yields confidentiality and integrity impact on protected resources.

Root Cause

The root cause is missing input validation on the OAuth scope parameter during dynamic client registration. The DynamicRegistrationRequest model performed validations for application_type, response_types, and grant_types, but no equivalent :scope validator existed to reject values outside Doorkeeper.configuration.scopes or optional_scopes.

Attack Vector

An attacker sends a crafted registration request to the DCR endpoint containing a scope value that includes privileged scopes never advertised by the server. The controller persists the supplied scopes onto the new application record. The attacker then completes an OAuth flow using the newly issued client_id and client_secret, receiving an access token that carries the escalated scopes.

ruby
# Vulnerable code path in dynamic_client_registration_controller.rb
        {
          name: params[:client_name],
          redirect_uri: params[:redirect_uris] || [],
-         scopes: params[:scope],
+         scopes: registration.permitted_scopes,
          confidential: registration.confidential_client?,
        }
      end

# Added validator in dynamic_registration_request.rb
        validate :application_type,           error: :invalid_client_metadata
        validate :response_types,             error: :invalid_client_metadata
        validate :grant_types,                error: :invalid_client_metadata
+       validate :scope,                      error: :invalid_client_metadata

Source: GitHub Commit 24c3cb1

Detection Methods for CVE-2026-70665

Indicators of Compromise

  • Records in the oauth_applications table containing scopes values that are not present in Doorkeeper.configuration.scopes or optional_scopes.
  • Access tokens issued with scopes that were never exposed through the server's discovery document.
  • Unusual bursts of POST requests to the Dynamic Client Registration endpoint from a small set of source IP addresses.

Detection Strategies

  • Audit the oauth_applications table and compare stored scopes against the configured allow list, flagging any deviation.
  • Instrument the DCR controller to log the raw params[:scope] value alongside the resulting persisted scopes for correlation.
  • Review authorization server access logs for token issuance events whose scopes fall outside the intended catalog.

Monitoring Recommendations

  • Alert on newly created OAuth applications registered without prior human approval, especially those with elevated scopes.
  • Track token introspection responses that report scopes outside the documented server scope set.
  • Forward Rails application and OAuth audit logs to a centralized analytics platform for retrospective hunting across the exposure window.

How to Mitigate CVE-2026-70665

Immediate Actions Required

  • Upgrade the doorkeeper-openid_connect gem to version 1.10.4 or later and redeploy affected Rails services.
  • Enable enforce_configured_scopes in the Doorkeeper initializer to force server-level scope validation.
  • Review all applications registered through the DCR endpoint since it was exposed and revoke any with unauthorized scopes.

Patch Information

The issue is fixed in Doorkeeper OpenID Connect 1.10.4. The patch replaces the direct assignment of params[:scope] with registration.permitted_scopes and adds a :scope validator to DynamicRegistrationRequest that rejects any value outside the configured scope set. See the GitHub Security Advisory GHSA-8r7r-wh7x-27ff for the official advisory.

Workarounds

  • Disable the Dynamic Client Registration endpoint entirely if it is not required by the deployment.
  • Restrict DCR access with an authenticated initial access token or network ACL until the patch can be applied.
  • Enable enforce_configured_scopes so the ScopeChecker validates requested scopes against server configuration rather than application records.
bash
# Rails initializer example: config/initializers/doorkeeper.rb
Doorkeeper.configure do
  default_scopes  :read
  optional_scopes :write, :profile
  enforce_configured_scopes
end

# Update the gem
bundle update doorkeeper-openid_connect
bundle list | grep doorkeeper-openid_connect  # verify >= 1.10.4

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.