All vulnerabilities
CVE-2026-49272GHSA-3jp2-3mrg-2vxc

OAuthLib: Bearer token can be retrieved as long as client knows a valid client ID for device workflow

oauthlibpipLibraries & packages
CVSS
8.5High
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)No scoreNo FIRST EPSS score in this snapshot yet
Fixed in4.0.0Fixed versionGitHub
Published27 Oct 2026Updated 27 Oct 2026GitHub

What fixes it

  • 4.0.0oauthlib, pipGitHub
  • 4.0.0oauthlib, PyPIOSVpip install "oauthlib>=4.0.0"

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Summary

A call to the token endpoint with a grant type of "urn:ietf:params:oauth:grant-type:device_code" and a bogus device_code is able to get a bearer token as long as they know a valid client ID enabled for the device workflow.

Details

Section 3.4 of the RFC 8628 spec says that the token endpoint should take in device_code as a required parameter.DeviceCodeGrant.validate_token_request does not perform any validation of device_code. DeviceCodeGrant.validate_token_request should be validating that device_code was passed in as a parameter and that it is valid, similar to how AuthorizationCodeGrant.validate_token_request does the checks here and here.

I would like to propose a new method be added to RequestValidator called validate_device_code that is similar to the validate_code method and is called inside of DeviceCodeGrant.validate_token_request.

PoC

Create an implementation of RequestValidation.authenticate_client that returns True if the client's client_type is "public". You would find yourself in this scenario because there's another issue with DeviceCodeGrant.validate_token_request where it doesn't properly handle public clients (see https://github.com/oauthlib/oauthlib/issues/919).

Create a client that has a client_type of "public" and set it's grant_type to "urn:ietf:params:oauth:grant-type:device_code".

With this implementation of RequestValidation.authenticate_client done, use that validator for your token endpoint. Call the token endpoint with a body of

{
  "client_id": <ID of the public client you made>,
  "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
  "device_code": <anything you want since it's not validated>
}

You now have a bearer token for the client without a valid device_code.

Impact

Anyone using the RFC 8628 device workflow in oauthlib that doesn't realize the device_code parameter is not being validated.

Text from GitHub Advisory Database

Affected versions 4

  • oauthlib, pip>= 3.3.0, < 4.0.0GitHub
  • oauthlib, PyPIfrom 3.3.0, fixed in 4.0.0OSV
  • oauthlib, PyPI3.3.0OSV
  • oauthlib, PyPI3.3.1OSV

References 3