spring-projects / spring-projects/spring-security

ClassCastException (HTTP 500) on /oauth2/token when single-value parameters are duplicated

Open
#19,227 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: bug
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Describe the bug

When the OAuth2 /oauth2/token endpoint receives a request with a duplicated single-value parameter (e.g. two code values), the server responds with HTTP 500 due to an unhandled ClassCastException:

java.lang.ClassCastException: class [Ljava.lang.String; cannot be cast to class java.lang.String

Per [RFC 6749, Section 3.2](https://datatracker.ietf.org/doc/html/rfc6749#section-3.2) (Token Endpoint):

Request and response parameters MUST NOT be included more than once.

And [Section 4.1.2.1](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1) explicitly defines this case as invalid_request:

invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.

The server should therefore reject the request with an OAuth2 invalid_request error (HTTP 400), not crash with an internal error.

Likely cause: when duplicate form parameters are sent, ServletRequest#getParameterMap() returns values as String[]. The OAuth2 token endpoint converters appear to assume each entry is a String and perform an unchecked cast, raising ClassCastException instead of a controlled OAuth2AuthenticationException(invalid_request).

To Reproduce

Send the following request against a standard Spring Authorization Server token endpoint:

POST /oauth2/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>

grant_type=authorization_code
&code=bogus-auth-code-a
&code=bogus-auth-code-b
&redirect_uri=https://example.com/callback
&code_verifier=xyz

Note the duplicated code parameter. The server returns HTTP 500 with the ClassCastException above.

Environment:

  • Spring Boot: 4.0.6
  • Spring Security: 7.0.5 (managed by Spring Boot 4.0.6; includes Spring Authorization Server, which has been folded into Spring Security since Boot 4.0)
  • Spring Framework: 7.0.7
  • Java: 25
  • Client: Apache HttpClient 5.6.1

Also reproduced on Spring Boot 4.0.3 (Spring Security 7.0.2).

Expected behavior

The server should return an OAuth2-compliant error response:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "invalid_request",
  "error_description": "OAuth 2.0 Parameter: code"
}

Single-value OAuth2 parameters (code, grant_type, redirect_uri, code_verifier, client_id, refresh_token, scope, etc.) appearing more than once should trigger OAuth2AuthenticationException with OAuth2ErrorCodes.INVALID_REQUEST, consistent with the existing "missing parameter" handling. The same defect likely affects /oauth2/authorize and should be fixed symmetrically.

Sample

(to be filled — link to a minimal reproducible sample repository)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the OAuth2 /oauth2/token request converters around ServletRequest#getParameterMap() and reproduce the duplicated code request described here. Verify that repeated single-value parameters produce an OAuth2 invalid_request response with HTTP 400 instead of ClassCastException and HTTP 500, then check whether the same handling applies to /oauth2/authorize.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
api, authentication, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.