Skip to content

getClient called with non-decoded secret/client #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MaximilianGaedig opened this issue Aug 5, 2023 · 3 comments · Fixed by #208
Closed

getClient called with non-decoded secret/client #213

MaximilianGaedig opened this issue Aug 5, 2023 · 3 comments · Fixed by #208
Labels
discussion 🗨️ Discussion about a particular topic.

Comments

@MaximilianGaedig
Copy link
Contributor

Here getClientCredentials takes request.body.client_id and request.body.client_secret without calling decodeURIComponent() on them:

// token-handler.js
TokenHandler.prototype.getClientCredentials = function(request) {
  [...]
  if (request.body.client_id && request.body.client_secret) {
    return { clientId: request.body.client_id, clientSecret: request.body.client_secret };
  }
 [...]
};

The result of this is not the client secret arriving at the getClient method, but the url encoded version of it, which in my case was base64 encoded so it was changed and the getClient method failed.

I think handling it in the model is not problematic but unnecessary so it should be done in the library

"Workaround"

class Model {
  async getClient(clientId: string, clientSecret: string | null): Promise<Client | Falsey> {
    const clientIdDecoded = decodeURIComponent(clientId);
    const clientSecretDecoded = clientSecret ? decodeURIComponent(clientSecret) : null;
    // use clientIdDecoded and clientSecretDecoded in your database logic instead of clientId and clientSecret
  }
}
@jankapunkt jankapunkt added the discussion 🗨️ Discussion about a particular topic. label Aug 6, 2023
@jankapunkt
Copy link
Member

jankapunkt commented Aug 6, 2023

Hi @MaximilianGaedig since the encoding of the secret is entirely part of the surrounding implementation, so is the decoding, too. We can't make any assumptions beyond the OAuth2 standard, which is why the model is one place where this should could be done. However, note, that your token endpoint could also be a place to handle such.

const server = new OAuth2Server({ model })

// ...other endpoints

// this could be added to express or other middleware
const tokenEndpoint = function (req, res, next) {
  const clientSecret = req.body.clientSecret ?? null;
  req.body.clientSecret = clientSecret ? decodeURIComponent(clientSecret) : null;

  const request = new Request(req);
  const response = new Resonse(res);

  server.token(request, response, options)
    .then(function (code) {
      // ...
    })
    .catch(function (err) {
      // ...
    });
}

@MaximilianGaedig
Copy link
Contributor Author

Ah okay, maybe documenting it would be a good idea, like including a notice by the getClient method

@jankapunkt
Copy link
Member

@MaximilianGaedig sure, I'm adding this to #208

@jankapunkt jankapunkt linked a pull request Aug 7, 2023 that will close this issue
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion 🗨️ Discussion about a particular topic.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants