2

In OAuth2.0 we have to send client id and secret along side the user credential to obtain an access token from an authorization server. We have a ReactJS web application that needs to send its request to API gateway (Main API), but problem arise when the web application wants to store the client secret for its requests: React JS and API gateway

In this scenario I am totally aware that storing the secret on web app would expose the secret to the WILD internet and everyone can create a new application from ground up and sends it request to API gateway.

What I came up with is to create a middleware gateway on server that would store the secret and its whole functionality would be to get an access token from API gateway by its secret and the client id which is given by ReactJS web application. enter image description here The whole responsibility of Secret Holder is that it just keep the secret for the web application and obtain an access token for the ReactJS app.

I've gone through all the questions below but could not satisfy myself to design an extra module for just serving access token for the web:

In the future we would definitely have iOS & Android applications too.

How do you guys handle your client id & secret in your web applications? Is the 2nd scenario good enough or is there a best practice that I'm unaware of?

I would appreciate if anyone could shed some light on this question.

5
  • I think you're misunderstanding some things here. Things like single page javascript apps (or other things where you can't guarantee being able to keep the client secret) typically don't use the secret at all. If you had made this secret keeper thing, what would prevent the "WILD internet" from just calling that instead? This link might be useful in helping with the OAuth2 flow, especailly without the secret.
    – Becuzz
    Dec 7, 2017 at 16:11
  • @Becuzz, well the only grant that can be used to get access token without client secret is the flow of Authorization Code Grant which does not make sense when the application is owned by myself. I cannot redirect user to another page and then ask for permission grant!
    – Alireza
    Dec 7, 2017 at 16:26
  • this question comes up a lot. in theory its impossible. but maybe if you add more detail on what your specific app is and what you are trying to prevent...?
    – Ewan
    Dec 7, 2017 at 17:02
  • @Ewan, What I'm trying to do is to prevent users to get the secret and send their requests to API Gateway in place of our React Web Application. The application is a social networking application that in the future will expose its REST API to third parties through client id and secret (paid plan). But if they already have access to secret key, then exposing API to 3rd parties means useless, as they can do whatever they want with the API Gateway.
    – Alireza
    Dec 7, 2017 at 19:24
  • Isn't your question actually "how do I make my public api private to me or my partners?"
    – Sentinel
    Apr 28, 2018 at 20:18

2 Answers 2

2

Your tl;dr version is "of course not", but the underlying issue here is a fundamental and very common misunderstadning of what secret really means in these contexts.

First things first, there is absolutely no way you can guarantee that a secret will remain ... well ... secret when distributed to client apps; that's regardless of whether they are web based or otherwise (mobile or IOT for example).

In fact, using AWS Cognito as an example, they even explicitly mention the above in their docs on client apps and secrets:

If a secret is created for the app, the secret must be provided to use the app. Browser-based applications written in JavaScript may not need an app with a secret.

And for good reason – what good is a secret in a browser app where anyone can right-click their way to it in a few seconds?

And even for clients distributed in a "packaged" fashion with no direct access to the source code like mobile apps, secrets can still be recovered; all you can do is obfuscate them and hope no-one is going to decide they really need to find them. They are merely an inconvenience to whoever might be attempting to do something fishy.

Actual secret comms can be enabled with flows involving a "server in between" but it comes down to the specifics of your situation. For example, borrowing from Cognito again:

For security reasons, we highly recommend that you use only the Authorization code grant flow, together with PKCE, for mobile apps.

They key thing to remember is if it leaves the app / is part of a request it is not a secret, and even if it doesn't it is still possible that it gets compromised.

Keep in mind that all the above hold true for client secrets / API keys when involving unauthenticated calls (e.g. sign up calls or API calls to get a products list on an e-commerce platform) only. Authenticated calls are a different thing and would require some sort of MITM attack or physical access to the attacked account to get ahold of.

Summing up:

  1. Client secrets and API keys distributed to client apps are simply outside of your control to keep secret by definition and as such should at any given moment be considered as good as compromised.

  2. Knowing the above, and assuming you want to "keep people off your back" you can include a rotation strategy for publicly distributed secrets to make it harder / inconvenient for people to get to them and (depending on how much effort you wish to spend on it) potentially identify them.

  3. You should still use them for mobile apps in combination with PKCE, just obfuscate them to the best of your ability first to minimize the potential of exposure (if and only if you're using them to calculate something like a HMAC locally or using some other way to protect them like SSL pinning) but keep in mind that even then people will still figure out ways to uncover them.

0

Just have your client id and secret change in each request for the app, make it expire early, and maybe link it to a refresh token too. If you want to prevent a client from accessing, revoke the refresh token. Store your dynamic client secret in secure cookie and ensure https.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.