What is the exact fallout of a compromised LinkedIn OAuth2 client secret? - oauth-2.0

Let's say I have a LinkedIn app used for OAuth 2.0 authentication. The app has a couple of permissions selected and a list of whitelisted redirect URLs. Let's say that I trust my LinkedIn credentials are secure, having been changed recently. Further, I have no reason to suspect that anyone malicious has gotten their hands on my app's client id or secret.
But now I need to respond to a what-if: What if I assume the client secret has been compromised?
What should my response be to this scenario? What is the worst an attacker could do with the client id and secret, but no access to the allowed redirect URLs?
Making a new app will be painful, because I will have to go through the approval process a second time to get the full profile permission added. And it sounds like this can take weeks to complete. Am I safe continuing with the "compromised" client secret for a few weeks, then deploying an update to use a new app when it is ready?

Related

Are there any security concerns with sharing the client secrets of a Google API project?

I'm working on a project using the YouTube Data API. The Python script I'm running uses a client secrets JSON file, which I presume is for verifying the account owner. If I am having issues with it and need assistance, are there any security concerns with sharing this publicly? Is it even alright if it's held privately in a private github repository?
If you check the Google Developer TOS which you agreed to when you created your account on Google developer console
It is against the TOS for you to share this file with anyone. This is secret and only intended for the developer or team of developers who created it. This pertains to the entire client secret json file you download from Google developer console or google cloud console.
Again DO not share your google secret file. No matter what the accepted answer stays about how problematic it may or may not, nor does it matter what type of client it is. Sharing the client secret file would be volatilizing the TOS you agreed to.
My corrections for another answer on this thread here
The answer in question has some statements that i strongly disagree with and feel may cause confusion to developers. Let me start by saying I am not an employee of Google, my comments are my own and from my experience with working googles oauth / identity server server for eight+ years and contact with google identity team. I am concerned that some of the information in the answer above may confuse some developers. Rather than just saying dont share them the other question tries incorrectly IMO to explain why it wouldn't be so bad to share them. I will explain why you should never share them beyond the fact that its against googles TOS.
The security implications depend on the type of client secret. You can tell the difference by whether the key in the JSON file is installed or web.
The type of client has no effect upon I how great the security risk would be. If we ignore the definition of what a constitutes a security risk completely and just say that any chance anyone could get access to a users account or authenticate a user on behalf of the project, would constitute to big of a security risk then there is no difference.
Using the following command I could authenticate myself all i need is the credentials file for your project
https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
This would only work 100% of the time for an installed application. Why is this bad if i am just authenticating my own user. I could then use my evil powers to send so many requests against the API that the target google developer project would be locked down by Google for spamming.
If i have stolen another users login and password i can login to them from your Google developer project and i have access to their data and Google thinks its you hacking them.
This is a little harder with a web application due to the Redirect URI, However a lot of developers include add localhost as a redirect uri when in development and forget to take it out (Please never leave localhost as a redirect uri when you are in proudcution) . So in the event you have left redirect URI as a valid redirect URI in a web browser client then I can do the exact same thing.
Remember I am now able to authenticate users based upon your project to access mostly my own data. However if you have also set up access to client data for example via google drive I may be able to access that as well. (Note: Im not Sure on this one i havent actually tried.)
If i have manged though man in the middle attack or some other means to get a users refresh token, and I have the client secret file I can now access users data because I can create new access tokens with my refresh token for as long as i want. This is probably a bit harder to achieve.
Web application secrets
If the client secret is of the web type, then yes: you should absolutely not post it, and invalidate it if it gets exposed. This would allow a malicious entity to impersonate your backend and perform actions on your users' accounts on your behalf.
As stated above this will only be the case if the developer in question has left the redirect uri open for localhost or the person who now has your client secret file also has access to your web server. One very important fact is that if you have left localhost open i can then put up my own website using your credentials and set it up so it look exactly like your website. Users then think they are logging into Your super awesome app when in fact they are logging into Hacker Super awesome app giving them access to the users data. Again google thinks its you hacking them.
Installed application secrets
If the client secret is an installed-type secret, then it's less problematic to share privately, as it doesn't grant the sorts of abilities a web application secret does, such as the ability to authenticate as users who grant your application permission to access their data. As the documentation notes, "in this context, the client secret is obviously not treated as a secret."
This is completely false Installed applications give the exact same permissions as web applications there is no difference with-regard to Oauth2 access an access token is an access token no matter if it was created for an installed application or a web application.
As stated above security risk with giving out access to your installed application this is actually worse. As there are no redirect uris with installed applications. Anyone that has access to your client secret file could authenticate users who assume they are you because they are being shown your consent screen. Not only is your Google developer project being hjacked but your reputation to your users who think that they are authenticating to Super awesome app and in fact they are not granting the person who has stolen your credentials access to their data.
I would like to add one last thing. If you give another person your project credentials. The client secret json file. You are giving them access to make calls on your behalf. If you have bulling set up lets say against google maps api. You will be charged for the calls they make.
I hope this helps to clear up some of the confusion related to the accepted anwser.
Yes, this is a problem. It's called a "client secret" for a reason. If it does become exposed, you should take steps to invalidate it and get a new one so that someone doesn't try to impersonate you.
Short answer: the security implications depend on the type of secret, but you should not share it publicly for other reasons, including the Terms of Service, which state that:
You will keep your credentials confidential and make reasonable efforts to prevent and discourage other API Clients from using your credentials. Developer credentials may not be embedded in open source projects.
The security implications depend on the type of client secret. You can tell the difference by whether the key in the JSON file is installed or web.
Web application secrets
If the client secret is of the web type, then yes: you should absolutely not post it, and invalidate it if it gets exposed. This would allow a malicious entity to impersonate your backend and perform actions on your users' accounts on your behalf.
Installed application secrets
If the client secret is an installed-type secret, then it's less problematic to share privately, as it doesn't grant the sorts of abilities a web application secret does, such as the ability to authenticate as users who grant your application permission to access their data. As the documentation notes, "in this context, the client secret is obviously not treated as a secret."
You still should not post it publicly on GitHub, a Stack Overflow question, or other public places, as posting it publicly increases the probability of someone copying your code in its entirety or otherwise using your client secret in their own project, which might cause problems and likely would run afoul of the Terms of Service. People trying to reproduce your issue could pretty easily generate credentials to drop into your code—credentials are a reasonable thing to leave out of a question.

How to handle access token in OAuth authorization flow?

I'm building an app that uses Github OAuth, which uses the authorization flow. This is my first time implementing OAuth, so I just wanna make sure i'm doing everything right. Im imagining something like:
User clicks Continue with Github. We call the GH url and provide a frontend app redirect uri. The app accepts a code and sends it to the server. It exchanges it for an access token, then gets the user from an API, gets the id and checks if that exists in the database. If it does, it creates a JWT token and sends a response like [token, ...].
I hope that's how it should be.
The question is what to do if the user doesn't exist. In that case I also want to ask the user for a username in my app (as well as accepting ToS etc). So I have two options: sending back the code or sending the access token.
If I send the code, once the user fills the username, the server will be querying for the access token again. Seems repetitive to me.
But since the access token is a function of my app secret, I'm hesitant for it to be on the client. Although these convince me otherwise:
access token should be a signature of the app secret, and shouldn't leak the app secret (right?)
we can assume app store is secure, because, well, it's the app's state
connection is SSL
So what's the best practice? Cheers!
Not sure about GitHub specifics - but the general Self Sign Up behaviour is for GitHub to manage this for you. After login your app will receive a token with a new user id. You will then need to create that user in your app's back end as well. My write up may help - it is tricky though: https://authguidance.com/2017/10/02/user-data/

How a mobile app will refresh access_token without refresh_token ? Implicit grant/ OAuth 2

As said in OAuth2 rfc6749
The implicit grant type is used to obtain access tokens (it does not
support the issuance of refresh tokens) and is optimized for public
clients known to operate a particular redirection URI. These clients
are typically implemented in a browser using a scripting language
Refresh tokens are not suitable for implicit grant.
My question is:
How a mobile app, will refresh the access_token once it expires?
How the big ones in the market are doing this? Which practices they follow?
I know it is not following security recomendations, but it´s a good practice to make an long-lived access_token in this case? It can get annoying to need to re-authenticate each 30 min you use an app, or you close and reopen it.
As necessary permissions don´t change, a silent log-in on every app start, will be a choice to consider?
You don't necessarily need a refresh token to allow continued usage once an access token expires. If you must insist your clients use the implicit flow, then they may be able to make use of cookies and redirects to keep getting short-lived tokens without user interaction. Providing your client apps are using an HTTP agent which can use permanent cookies. e.g. apps that run in a web browser.
The key then is keeping the user signed into the identity provider the first time the token is requested.
This is done for example by the Identity provider (you I guess?) creating an HTTP cookie for the user agent to persist. Most big identity providers will do this - i.e. keep you signed in.
Now, when the token expires your client app will send the user back through the Oauth process again but, because the user has remained logged in to the identity provider, the identity provider can authenticate the user from the cookie without prompting for credentials.
If your clients instigate this token renewal on a background thread they can request the token as normal and, through the magic of HTTP redirects and cookies, get back a new token from you with no user action required.
Again - this alternative to refresh tokens relies on the client device being able to utilise permanent cookies, and your users remaining signed in and your auth server handling http cookies. If your clients are using native apps this solution may not work.
As in the future you will have 100s of clients maybe your auth plaform should offer different auth flows to different clients.
This article on mobile apps and implicit flow may be of interest to you.
Native apps are supposed to use the Auth code grant. So you can use refresh tokens. There is an RFC that discusses reasons (mainly security) for that as well as platform specific details. There is an important implication - the /token endpoint of your OAuth2 provider should not require authentication for getting tokens, because your application cannot keep its client secret safe.

Receive cross-client Google+ authorization code for offline access without library on iOS

It's funny but I can't find description of using HTTP requests to receive Google+ authentication code for offline access without iOS Google+ library.
Though example of it's integration is pretty straightforward, I don't want to add additional 20mb of weight to my iOS app.
I tried the approach described here
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
but in case of server clientId I receive message abount incorrect redirect uri.
Could someone give me advice about it?
There are two approaches you could take that may/may not work for you.
Installed app flow with internally stored client secret
Web flow within a web view.
Installed app flow
You will must likely need to use the offline OAuth v2 / installed app flow which has redirect URI that has something like urn:ietf:wg:oauth:2.0:oob enabling you to redirect back to the browser, from there you can get a code to exchange for tokens.
In your case, I'm guessing you didn't create the right client type (installed application) which is preventing the *:oob redirect.
It's less secure to handle sign in in this way - if the user can extract the client secret from your app, they can do bad things like authorize a malicious 3P app with access to your application data.
Web signin flow
An alternative would be to use the web signin flow from within a WebView, something that Apple may reject your app for and which is also insecure.
What you would do is host the sign-in solution on your web server, use the JavaScript web signin flow to initiate sign in, request offline access, then exchange the resulting code for an access token and refresh token.
You would then store the refresh token / access token on the device and exchange it for an access token when you need access to the user data or exchange the refresh token server-side and pass the bearer token back to the iOS app when it needs access. This again is bad because it can expose other apps to user authorization credentials and could potentially allow a malicious 3P to access user data.
I can't recommend either approach. Is there a reason other than the app size impact that you can't use the library? I'll see if there is a good way to avoid the file size hit from the framework.

OAuth - How is it secure?

I am writing some code to get Twitter and Instagram feed. Before I can write any code, I keep wanting to get a good understanding of oAuth because I have this nagging feeling that it is not all that secure and that most times, for instance when accessing public tweets, it is an unnecessary hassel. I started reading the oAuth 2 specification to get a better understanding, I am still in the middle of it. And I have a host of questions.
Let's use Twitter as an example.
A user accesses your site. You redirect them to Twitter for authentication and to obtain the authorization_grant code.
I understand this part is secure because the user authentication and the redirect to your website will happen over ssl. Is it enough for Twitter to support SSL or does your site also have to support SSL for the redirect to be secure? You wouldn't want the authorization code to be transferred insecurely, right?
Now that you have your authorization_grant code, your site will send a request to Twitter to obtain an access token. When making this request your site will send the authorization_grant code, your client id and client secret. Again I guess the communication is secure because this will happen over ssl. But what if the site has included the client id and secret somewhere in its HTML or Javascript, especially if it is a static site with no server side code?
Should the redirect url always be handled by server side code and the server side code should make the request for access token without ever going through HTML or Javascript?
Once you have the access token, you will include it in your request to obtain the user's tweets, to post tweets on their behalf etc. Again if the site in question were to include the access token inside its HTML or JavaScript along with the client id and secret, that would be pretty insecure, right?
It seems all the security of oAuth stems from ssl and the client's ability to keep their client secret secret. Am I right in this conclusion?
Another thing - in the first step of the process, when the client redirects the user to Twitter to authenticate and obtain the authorization_grant code, they could send in their client id and secret and get the access token directly instead of making a second request for it. I think this is what they mean by the implicit method in the specification.
So, why was this extra step of sending a second request to obtain access token added in the specification? Does it increase security?
I am not sure about twitter API, I am talking with respect to stackexchange API
https://api.stackexchange.com/docs/authentication
Again I guess the communication is secure because this will happen
over ssl. But what if the site has included the client id and secret
somewhere in its HTML or Javascript, especially if it is a static site
with no server side code?
client_secret is send only in the case of explicit flow. Explicit flow should be used by server side application and care should be taken to keep the client_secret safe.
So, why was this extra step of sending a second request to obtain
access token added in the specification?
Well, Implicit flow is less secure than explicit flow since access toke is send to the user agent. But there is an attribute expire in the case of implicit flow which will get expired unless you have specified scope as no_expiry. Also server side flow can be used only by the apps that are registerd
It seems all the security of oAuth stems from ssl and the client's
ability to keep their client secret secret. Am I right in this
conclusion?
Again client_secret will be available in server side flow. But yes, client should take care that access_token is not given out
Check out this link. It gives an example of possible vulnerability in ouath.

Resources