cloudflare / cloudflare/workers-oauth-provider

fix: enforce client's registered `grant_types` at /token

Open
#210 1 comment 0 reactions 0 assignees View on GitHub
bug v1
Dominant language
TypeScript
Stars
1.9k
Forks
134
PR merge metrics
No merged PRs in 30d

Description

## Problem

The token endpoint dispatches on `body.grant_type` (`src/oauth-provider.ts` ~L1979) without checking the client's registered `grant_types` array. A client that DCR-registered with `[\"authorization_code\"]` can still successfully exchange a refresh token or, with EMA configured, a `urn:ietf:params:oauth:grant-type:jwt-bearer` assertion.

Per RFC 7591 §2 and RFC 6749 §10.6, the AS SHOULD reject grant types not in the client's registered set. RFC 8414 also requires `grant_types_supported` to be the AS-wide list — the client-specific allowed set is per-client.

## Repro

1. Register a client with `grant_types: [\"authorization_code\"]` only.
2. With EMA enabled on the AS, POST `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer` to `/token` with a valid ID-JAG.
3. Observed: 200 OK with access token.
4. Expected: `400 unauthorized_client` (grant type not permitted for this client).

## Suggested fix

In the dispatch in `handleTokenRequest`, after resolving the client, check that `clientInfo.grantTypes` (which is already stored at registration) includes the requested grant type. Reject with `unauthorized_client` if not.

The default for clients registered without specifying `grant_types` is `[\"authorization_code\"]` per RFC 7591, so this enforcement also closes the implicit-acceptance gap for refresh-token and jwt-bearer.

## Reporter

Surfaced during EMA integration testing by an external partner.

Contributor guide

Open the contributing guide

Research direction

Start in src/oauth-provider.ts around handleTokenRequest and the dispatch near line 1979. Trace how the resolved client’s clientInfo.grantTypes and the registration default are represented, then verify that a disallowed refresh-token or JWT-bearer request returns unauthorized_client rather than an access token.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, authentication, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.