My question mostly pertains to OpenID Connect, but can be applied to OAuth 2.0 as well.

When it comes to an OpenID Connect Client doing the "authorize" dance with the OpenID Connect Provider, the client sends its Client ID to the Provider to state which one it is. This is used in places such as the "consent" screens, which prominently display which scopes you are willing to allow the client to use with the Relying Party as a part of the access tokens that will be issued. The Client ID might also be marked as "special" in some way, like if it is for an "official app" it might allow this app to bypass certain consent screens that would otherwise be displayed to a third-party or display prominent visual cues to the user that this is an official "trustworthy" app.

My question revolves around to how to prevent said apps from being impersonated. With server-side apps these are protected through the use of a "Client Secret" which is unavailable to a malicious client. With browser-based clients (using the "implicit" flow), the "Client ID" is bound to a specific post-authentication redirect, which means a malicious client that is fraudulently using the "official" client's Client ID would never see the granted tokens, since the browser would redirect back to the wrong place (or the redirect URL would be rejected.

How do native apps, such as iOS or Android apps prevent against this kind of attack where the Client ID/Secret is stolen out of a legitimate app and used by a rogue app to impersonate it during OpenID Connect auth flows? As far as I see it, I could "steal" the Client ID (and/or the Client Secret) embedded in the "official" app, upload a rogue app to the App Store/Play Store that uses said ID/Secret, and then make sure the redirect URI that's used is the same as the official app. My rogue app would then listen to that redirect URL for the resulting tokens, and during the authorization dance the screens displayed to the user would prominently state that this is an "official" app and/or bypass those consent screens entirely, even though this is a third-party app.

(Sorry for the wall of text leading up to the question! Just wanting to make sure all of my assumptions are correct! Please, tell me if I have anything wrong!)

Stealing the client secret is becoming increasingly more difficult since these can now be stored using hardware APIs for encryption/safe storage on modern devices. Mobile applications should use those to the fullest possible extent.

Some time ago, the advised flow to use for mobile apps was the implicit flow - no client secret and no way to get a refresh token, which limited the possible window of attack.

These days I'd advise the Hybrid flow (code id_token), which does allow refresh tokens and thus also requires a secret. That secret must be stored as safe as possible, and additionally you should implement PKCE protection. PKCE protects against code interception attacks, not unlike what you describe: a malicious app could steal the auth code by registering the redirect URI/scheme. PKCE protects against that by requiring you to send over a code challenge (generated from a cryporandom code verifier) when sending the auth request. On each request to the token endpoint, the verifier is sent. That allows the IDP to check this against the challenge, which ensures tokens are only delivered to the correct redirection URI.

Hope this helps :)

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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