question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

id_token detected in the response, you must use client.callback() instead of client.oauthCallback()

See original GitHub issue

Provider type

Custom provider

Environment

  System:
    OS: Windows 10 10.0.22000
    CPU: (16) x64 AMD Ryzen 7 5800X 8-Core Processor
    Memory: 15.52 GB / 31.95 GB
  Binaries:
    Node: 16.15.0 - ~\scoop\apps\nodejs-lts\current\node.EXE
    Yarn: 1.22.18 - ~\Development\project\node_modules\.bin\yarn.CMD
    npm: 8.5.5 - ~\scoop\apps\nodejs-lts\current\npm.CMD
  Browsers:
    Edge: Spartan (44.22000.120.0), Chromium (101.0.1210.39)
    Internet Explorer: 11.0.22000.120
  npmPackages:
    next: 12.1.4 => 12.1.4
    next-auth: ^4.3.1 => 4.3.1
    react: 18.0.0 => 18.0.0

Reproduction URL

https://github.com/buehler/next-auth-issue-id-token

Describe the issue

When using an OIDC compliant identity provider, the custom provider configuration does not act according to the specification. If configured with idToken: false, the provider - if compliant to the standard - will nevertheless return an id token. This because of the fact that the returned information from the user-info endpoint MUST be validated against said ID token (the sub, to be specific).

As can be seen in: https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse The return value of a successful token response MUST contain an id token.

The reason is stated here: https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse

NOTE: Due to the possibility of token substitution attacks (see Section 16.11), 
the UserInfo Response is not guaranteed to be about the End-User identified by the 
sub (subject) element of the ID Token. The sub Claim in the UserInfo Response MUST
be verified to exactly match the sub Claim in the ID Token; if they do not match, 
the UserInfo Response values MUST NOT be used.

Currently, the client.oauthCallback function does throw an error that it has detected an id token and therefore the client.callback shall be used.

This is (in my opinion) a security issue.

How to reproduce

edit: the reproduction url contains a pre configured next-auth-example

Create a simple next auth application and use a custom provider. I used “zitadel” (zitadel.ch) as my identity provider since it is OIDC certified and adheres strongly to the specification.

Then, use the following configuration:

const provider = {
  id: 'zitadel',
  name: 'zitadel',
  type: 'oauth',
  version: '2',
  wellKnown: 'https://issuer.zitadel.ch',
  authorization: {
    params: {
      scope: 'openid email profile',
    },
  },
  idToken: false,
  checks: ['pkce', 'state'],
  client: {
    token_endpoint_auth_method: 'none',
  },
  clientId: '160657439937654201@for_next_auth_issues',
};

The configured return url is: http://localhost:3000/api/auth/callback/zitadel (for the next app).

With this configuration, the following error is thrown:

[next-auth][error][OAUTH_CALLBACK_ERROR] 
https://next-auth.js.org/errors#oauth_callback_error id_token detected in the response, you must use client.callback() instead of client.oauthCallback() {
  error: {
    message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()',
    stack: 'RPError: id_token detected in the response, you must use client.callback() instead of client.oauthCallback()\n' +
      '    at Client.oauthCallback\n' +
      '    at processTicksAndRejections\n' +
      '    at async oAuthCallback\n' +       
      '    at async Object.callback\n' +
      '    at async NextAuthHandler\n' +
      '    at async NextAuthNextHandler\n'
    name: 'RPError'
  },
  providerId: 'zitadel',
  message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()'
}

Expected behavior

First of all, the callback must not throw this error because the response is actually compliant with the OIDC standard (in https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse). Additionally, the sub in the delivered ID token must be stored and when calling the user info endpoint to fetch the profile, the stored sub must be checked against the delivered sub by the endpoint. If they do not match, then it’s save to throw an error or something (as stated in https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse).

Debatably, one could argue that an error must be thrown, if NO id token is returned in the token response, since that is not compliant and does not allow the check for the sub on the user info endpoint.

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:3
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
balazsorban44commented, May 11, 2022

You are forcing the OAuth 2 flow with idToken: true, while also passing the openid scope. Removing that scope should resolve your issue.

0reactions
buehlercommented, May 12, 2022

FYI @balazsorban44: When using the suggested settings, with the removed openid scope and idtoken: false, the following error occurs:

[next-auth][error][OAUTH_CALLBACK_HANDLER_ERROR] 
https://next-auth.js.org/errors#oauth_callback_handler_error invalid_scope {error: {…}, error_description: 'The scope openid is missing in your req…t the administrator of the application.', body: '', providerId: 'zitadel', message: 'invalid_scope'}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Okta callback error v4 #3383 - nextauthjs/next-auth - GitHub
oauthCallback() { error: { message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()' ...
Read more >
id_token detected in the response, you must use client ...
oauthCallback()', stack: 'RPError: id_token detected in the response, you must use client.callback() instead of client.oauthCallback()\n' + ' at Client.
Read more >
Callbacks | NextAuth.js
Callbacks are asynchronous functions you can use to control what happens when an action is performed.
Read more >
next auth oauth callback error - You.com | The AI Search ...
oauthCallback() { error: { message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()', stack: 'RPError: ...
Read more >
Add Login Using the Authorization Code Flow - Auth0
Denotes the kind of credential that Auth0 will return ( code or token ). For this flow, the value must be code ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found