If you use Doorkeeper to handle OAuth 2 authentication in your Ruby on Rails or Grape APIs, you need to know about a major vulnerability discovered last year, officially tracked as CVE-2023-34246. This quiet bug could let attackers impersonate users without their consent, particularly when dealing with so-called “public clients.” Here, I’ll break it all down simply—code, risk, and what you should do.

What is Doorkeeper and Who is at Risk?

Doorkeeper is the go-to OAuth 2 provider gem for many Rails and Grape projects. It allows third-party apps to request access to your users’ data, powering everything from single sign-on to mobile app authentication. OAuth 2 distinguishes between *confidential* clients (like secure backend apps) and *public* clients (like single-page JavaScript apps or mobile apps that can’t securely hold secrets).

Public clients are riskier because there’s no way to guarantee their identity—they can’t safely store credentials. That’s why OAuth 2 implementations usually take special care to always require user consent for these apps.

Before version 5.6.6, Doorkeeper would automatically allow OAuth authorization requests from public clients if the user had previously approved that client. This means users wouldn’t see the consent screen again.

That sounds convenient, but here’s the catch: anyone can impersonate a public client simply by copying its client ID. Once the link between the user and a client is established, and the consent was given once, anyone pretending to be that client could get access tokens—no new prompt, no user awareness.

# Pseudocode - Simplified for clarity
if client_is_public && user_has_previous_approval
  # BAD: silently grant authorization without re-prompting the user
  auto_approve!
else
  ask_user_for_consent!
end

This means an attacker only needs to register a public client once and can later spam the endpoint for new tokens—acting on that user's behalf as soon as they're authenticated with the Rails app.

3. Attacker then crafts requests pretending to be that client (using its public client ID, which isn’t secret).

This is unfixable at a user or client level because, by definition, public clients are not secured.

Why Is This a Problem?

- No identity assurance: Anyone can act as the “public client” by knowing its client ID (which is easy to discover or guess).

- Shadowy impersonation: Access tokens flow to unauthorized parties, possibly exposing sensitive user data.

How It Was Fixed

Doorkeeper 5.6.6 updated the consent logic. Public clients always require user consent, regardless of previous authorizations. Here’s a safe pattern (post-fix):

if client_is_public
  # Always ask for user consent for public clients
  ask_user_for_consent!
elsif user_has_previous_approval
  auto_approve!
else
  ask_user_for_consent!
end

Now, no public client can silently get new tokens—the user has to explicitly okay every authorization attempt.

Upgrade immediately: Move to at least Doorkeeper 5.6.6.

- See upgrade guide

Official References and Further Reading

- CVE-2023-34246 Advisory
- Doorkeeper 5.6.6 Release Notes
- Upgrading Doorkeeper Guidance
- Original Commit Fix

The Bottom Line

If you use Doorkeeper in your Rails or Grape app, especially with public OAuth clients, update now. Prevent attackers from silently acting on behalf of your users. As OAuth 2 grows more popular, subtle bugs like CVE-2023-34246 remind us of the importance of vigilance—even in trusted libraries.

*Stay secure!*

Did this help? Want more breakdowns of Ruby and Rails security? Let me know below or subscribe for alerts!

Timeline

Published on: 06/12/2023 17:15:00 UTC
Last modified on: 07/12/2023 15:15:00 UTC