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.
# 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.
# 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.

