Why OAuth API Keys and Secrets Aren't Safe in Mobile Apps

Why OAuth API Keys and Secrets Aren’t Safe in Mobile Apps

Let’s take a look at two ways it’s possible to hack secret API keys out of mobile apps.

Mark Heckler

Excellent article! One small quibble with the C program, though: you mention it has a single string named example, but the code itself rather shows two char arrays, hello and world. Likely just a revision/editing error, but I wanted to let you know. :slight_smile:

Again, thanks for another great article!

aaronpk

You’re totally right, thanks! I originally had written the program with a single string, then realized it made a better example to have it as two strings in the program. Forgot to update the article text to match!

Mark Heckler

Been there, done that. :joy:Thanks for the article, Aaron!!

mehdi mohammadi

Thanks for this useful article, my question is this at first step user needs to pass secret key to get access token/refresh token so we could not say that on oauth2, secret key is not being shipped at all. Am I right?

aaronpk

It’s entirely possible to complete an OAuth 2.0 flow without using a secret key at all. This post talks about the details of it, hopefully that answers your question: https://developer.okta.com/…

Michał Karolik

Getting back to times when implicit flow was recommended for mobile/js apps - why not having client secret was considered safer? If someone could steal client secret he could also steal client id? What exactly made it a little bit better than authorization_code with secret?

aaronpk

The client_id has always been considered public information, so there is no risk of it being stolen.

Without PKCE and without a client secret, there is no protection against the access token being stolen from the redirect in the implicit flow, and it has always been known that this is less secure. The implicit flow has never been recommended as a secure option, it was just the only option at the time.

If a mobile app were to include a client secret and use the authorization code flow, there would also be no protection against stolen authorization codes, since the secret wouldn’t be secret and would be available to an attacker.

Amir

Hello Aaron,

first of all, thanks for your nice article,

I have a question with regard to a scenario that maybe I didn’t understand it correctly, I will be gratefull if you could help to make it more clear.

I read, in a lot of places that people discuss that you can securely store the client_secret on the Application backend and exchange the code on the Application backend.

if I understood correctly, this means that, the app still start the code flow, but then forward the code into its backend to exchange the code for a token by using server-to-server communication. my question is that, in this kind of scenario, how the application backend authenticated with the IdP? does it include some parameters that are Referred to the native client or not?

thanks in advance

Ramanathan Vishnampet

I’ve seen some blog articles recommending not to make even the client_id public. If I’m using the PKCE flow, is it safe to include my client_id in the frontend javascript code? What’s the worst that an attacker could do knowing the client_id but not the client_secret.

aaronpk

There’s no way not to make the client_id public. Can you share the links you’ve found that say not to? I will go leave some comments there :slight_smile:

The worst an attacker can do is impersonate your app or attempt to initiate an OAuth flow for your app. This will only succeed if they can also control the redirect URL on the victim’s device.

Victor

Thank you, we have implemented the use PKCE. However, what is the recommendation when the API we want to consume is the OKTA API itself? Particularly, a mobile app that requires to manage the user account (ex. change password)

Anil Thakkar

Nice Article! I am stuck with one very basic requirement in my application. Here is my scenario. I am building custom e-commerce portal using angular as a front end and rest API as a back end. I have product listing API which is going to be called by my angular client application without user’s credentials as product list is public page. However, I don’t want anyone else to consume my product listing API. I know I can use client id and and client secret to obtain token and make it secure but, how do I avoid exposing my client secret in angular app?
Anyone can steal it very easily. Is there any way to use Authorization Code flow with PKCE for public my APIs such as product listing API where user id and password is not required?

Husni

I’m still confused why the client secret need to be kept secret. Let’s say that the client secret in your mobile app X is compromised by an attacker. The attacker can then use the client secret and pretend to be app X to authenticate a user and make them click “authorize this app” button. This will trigger redirect to redirect_uri provided in the authorization request. But, the attacker can’t use a their own redirect_uri since it needs to be registered to the client id first. This will be an obstacle for the attacker to obtain authorization code. Since the attacker can’t obtain the authorization code, they can’t get the user’s access token.

cw

The problem is that the redirect_uri goes back to whoever sent the authorization request as part of the redirect response after authentication. This means the malicious app can just look at the the URI in the response to get the authorization code.

disqus_74PaJwhTor

Hi, did you find an answer to this??

Daniel Martín

Could you elaborate on the consequences of having a client secret stolen? Thank you!

I’m facing a dilemma here. I’m trying to support Login with Twitter through Restful API’s flow. All tutorials that we see online either guide you on how to implement it on Browser, or how to implement it on Mobile without any mention of backend systems. On the latter guidelines, client key and secrets seem to be saved on the App. How is it possible to implement Sign in with Twitter on Mobile app when you shouldn’t save those keys?