Should I use client_secret in a native, public downloadable application? - oauth-2.0

I've read a lot about the different flows (authorization code, implicit, hybrid and some extensions such as PKCE). Now I'm on the authorization code flow with PKCE.
PKCE ensures the initiator is the same user as the users who exchanges the authorization code for an access token. That is nice and OK.
When using this flow without a client_secret (which is recommended for SPA/Javscript applications) there is no warranty that the client is the known/original client. So, the 'consent' the user gave, is of no value. uhh?
I am working on a nativate client (a public downloadable binary). A secret cannot be considered confidential when baked in the binary, it can be decompiled for example.
Now I'm in dubio. What is better, bake the secret in the binary so that there is some extra layer of assurance the client is the known client or stop asking for 'consent' and give the same client_id to the whole world, only relying on the user-credentials.
Or is there something wrong with my story?

Very good question and made me realise a gap in my understanding. It is the role of the redirect uri to deal with this risk. In the web / https case the only hack that could work would be to edit the hosts file of the user. I'm the native case it is less perfect and your question is covered below. Generally our best bet is to follow recommendations / standards - but they have plenty of problems! https://web-in-security.blogspot.com/2017/01/pkce-what-cannot-be-protected.html?m=1

To others reading this case I've read a lot more.
Client impersonation is not easy fixable.
RFC8252 seems to be the most applicable article with recommendations for native apps - https://www.rfc-editor.org/rfc/rfc8252
"Claimed ‘https’ scheme" is mentioned as the best solution (IOS, Android and maybe UWP apps).
Since I'm working on a native Windows, non-UWP application I can't use this. As far as I can see the "Web Authentication Broker based on the app SID" is possible for my situation.
The other method is to accept the client as not known/identified and ask for 'consent' every time the client would access personal data.

Related

Doesn't OAuth 2.0 PKCE Flow open the door to masquerading/phishing attacks?

With OAuth 2.0 PKCE Flow for Installed App (e.g. a desktop app/cli/client library), it seems that nothing is preventing an attacker to:
obtain client_id by using the original app (client_id is public and can be easily copied from browser bar/source code)
make a fake app to mimic original app
use the fake app to seduce the user to grant access and thus obtain a refresh token which essentially means full access within requested scopes
Without PKCE, it's hard to fake an app and obtain a refresh token because that would require an attacker to obtain client_secret. It seems to me that, although PKCE offers security improvements over implicit flow, it makes it so much easier to masquerade authentic apps that use OAuth 2.0?
I'm using googlecloudsdk (gcloud), it seems that it has client_id (and even many client_id/client_secret pairs) hard coded into the source code, which is distributed to the client. I doubt there's anything to stop attackers to fake gcloud and thus gain access to user's GCP environment (for proof, run gcloud auth login and it will show you the url in the console that an attacker needs.) Could anyone clarify/help me to understand what's going on?
Private URI schemes are probably the best you can do on desktop but are not perfect as you say. It is what I use for my Desktop Code Sample, but ideally I'd also like to resolve the above concern.
For mobile you can use Claimed HTTPS Schemes to solve the problem - see the answer I added to the post sllopis sent.
I would be aware of Updated OAuth 2.1 Guidance for Native Apps - see section 10 - but I don't think you can fully solve this problem.
It is expected that end users are careful about desktop apps they install, to reduce risks for this scenario. Hopefully operating system support will enable better cryptographic options in future.
Just wanted to follow up on this because I had the same question myself, but also answered it myself and I wanted to add something that wasn't said here:
When you set up the application on the oauth2 server, you have to set up a number of redirect_uris, allowed places to return to after authorization is complete. This means that someone who creates a phishing attack like the one you described cannot return to their own app after login, and will never receive the code.
There is a separate attack where you try and return to a legitimate app from an illegitimate app, however this is solved by the inclusion of the state variable.

OAuth2 Authorization Code Flow - exchange authorization code on Frontend VS Backend? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
i am developing an application with Angular Frontend and Java/Spring-Backend. For logging into our backend we are using Oauth2 Authorization Code Flow with PKCE and Open ID Connect.
When the user navigates to a protected route he is redirected to his IDP and has to login. After that he is returned to a redirect_uri with the authorization_code as URL parameter. So far everything is clear.
Now I am not sure what the best way to exchange this code for the access_token is? So far I've done this on the client (in JavaScript) and used the received JWT for further backend calls (on the backend I just verify the signature) and that does seem to work. But in other projects I've seen that colleagues actually used the backend kind of like a proxy. So they send the authorization_code to the Java-backend and the backend does the exchange.
Now I've read a lot, but can't seem to grasp the full implications of that. It does seem to me that it's safer to have the client/frontend do this. But on the other hand the backend is actually trusted, so we could actually use a client_secret in this case.
The question now is: Are both cases considered safe? Or is one considered more secure and if so: why?
Thanks in advance
*Edit: Just to clarify - we don't really need to access another resource server, the use case is that we just want to be safely authenticated to our own backend - once authenticated we switch to a session cookie anyway, so we don't store the access_token anywhere at all
Keeping the tokens in the backend is always a more secure approach because it reduces the attack surface and makes the code in the client much simpler.
A good starting point is to take a look at this BCP
OAuth 2.0 for Browser-Based Apps (section 6.2)
Another reference is:
Cheat Sheet: OAuth for Browser-Based Applications (e.g. a JavaScript SPA)
To make your JavaScript simple, I would do all the client authentication in the backend and when the backend gets the token, then create the session with your client. In that way the JavaScript client does not need to touch any tokens. Your internal resources/API would be accessed through the service that is responsible for the session. Clean and simple! :-)
yes! I think the classic mistake is to let JavaScript touch your tokens. You will sleep much better at night knowing that the tokens are only handled in the backend. Also, less security complexity and things you must master and understand! We must fight complexity!
The actual authorization code can only be used once so it doesn't matter if it is sent from front end or back end.
There are two common models here:
OPTION 1: WEB BACK END / PROXY PATTERN
This is used if you want to keep tokens out of the browser and use HTTP only cookies as a back end credential instead:
Web back end issues a same domain HTTP only cookie and stores tokens in either a database or the cookie itself
Web UI makes all API calls by first calling the web back end with the cookie
Web back end then looks up tokens and forwards them to the API
You need to deal with web threats such as CSRF and XSS
Challenges are:
More complexity than you'd like
Some architecture limitations
OPTION 2: SPA PATTERN
This is the cross domain model you are using and is technically simpler up to a point::
Web UI makes API calls by sending an access token
You need to deal with threats such as XSS and focus in particular on ensuring that use of tokens in the browser is no less secure than use of cookies
You need to store tokens in a secure manner in the browser, such as in memory
Challenges are:
If you have gaps in your security they will be easier to exploit since users can more easily see their own tokens
Token renewal and cross tab navigation aspects are trickier in this model.
FACTORS
These are the main factors when making a choice:
Security threat model - tokens v cookies and other factors
Wider architecture goals for Web UIs
Perception of stakeholders is often the single biggest consideration
Whatever you decide I would recommend starting with requirements rather than a particular technology stack.
RESOURCES OF MINE
I prefer option 2 since I think the architectural options are far better, but it requires care. The following links hopefully help you understand how I reasoned out my preferred solution:
Web Architecture Goals
Threat Model - Cookies v Tokens
End State and Cloud Deployment
Not everyone agrees with me though. Sometimes in software there are multiple solutions. What is important is that security threats are covered. You can potentially do that with either solution.
When your are called token from your client it's not the authorization flow it's implicit flow, and it's could be used when you don't have backend, and when you have backend you always should use authorization code flow as you've mentioned. You can learn more about openid flows here.
Authorization code flow is considering more secured because it use backchannel communication(server to server) with idp for receiving tokens, while implicit flow send request from browser.
Sending client calls with PKCE is new technology and it's considered as safe but definitely authorization code flow is better choice for backend.

Significant differences between Cookies and JWT for native mobile apps

I have been using Cookies for authentication and session control in my web apps, and am content with its functionalities.
I was introduced by an iOS app developer that the new hot thing is JWT (JSON Web Token). He told me that JWT is the way of doing authentication and sessions for native mobile apps, and without giving specific examples, he suggested that both iOS and Android apps have various problems with Cookies.
So I looked up JWT, e.g. http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/ and https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/, and I failed to see why it is significant better (or even that different) than Cookies, and more specifically, why it does better in native mobile apps. It seems that, at least iOS, handles Cookies just fine (Persisting Cookies In An iOS Application?).
So my question is, for a native mobile app that interacts with a server-side API, what are the specific advantages and associated use cases for using JWT over Cookies for authentication and sessions? Please highlight the ones that Cookies simply cannot do or does it much worse.
We software developers (sometimes) have the tendency to apply the new hot thing everywhere we look; it's possibly a variation of the saying if all we have is an hammer, everything looks like a nail where in this case we just feel a desperate urge to use this new thing we learned about.
One interesting point about this comparison is that neither JWT or Cookies are in fact authentication mechanisms on their own; the first just defines a token format and the second is an HTTP state management mechanism. Only this is sufficient to give us an indication that advocating that one is better than the other is wrong.
It's true however that both are vastly used in authentication systems.
Traditional server-side web application have used cookies to keep track of an authenticated user so that they were not forced to provide their credentials at every request. Normally, the content of the cookie would be an (hopefully) random generated unique identifier that the server would use to find session data stored on the server.
However, for a new type of web application - the API - it's more much more common to accept a token (in JWT format most of the times) as a way for the server to decide if it should grant access to who's making the request. The reason for this is possibly because while a traditional web application had one major type of client, the web browser, which has full support for cookies, the API's are generally used by much simpler HTTP clients that don't natively support cookies.
I think this is also why we could possibly argue that token based authentication makes more sense for native mobile applications. These applications generally depend on a server-side Web API and we've seen that if the API supports tokens it will increase the range of clients that can use it, so it's just the most practical thing to do.
In conclusion and to try to answer your concrete question, I would say JWT's do have an advantage over cookies on native mobile applications just because of the fact they are currently in very common use, this means more learning resources, SDK's, known pitfalls (mostly because someone else already did it and failed), etc.
Nonetheless, only use them if they give you the security assurances you need and end up simplifying your scenario. If you haven't gone through it already, I think you'll also appreciate Cookies vs Tokens: The Definitive Guide.
I cannot speak for Android but on iOS cookies work with URLSession as good as headers. Once you can utilize the (standard) API right (e.g. dedicated, properly configured session with cookie storage per web app...), iOS should be a rather negligible factor to this decision.

oAuth implementation from the beginning or later

I'm starting a new system creating using .NET MVC - which is a relatively large scale business management platform. There's some indication that we'll open the platform to public once it is released and pass the market test.
We will be using ExtJs for the front-end which leads us to implement most data mining work return in JSON format - this makes me think whether I should learn the OAuth right now and try to embed the OAuth concept right from the beginning?
Basically the platform we want to create will initially fully implemented internally with a widget system; our boss is thinking to learn from Twitter to build just a core database and spread out all different features into other modules that can be integrated into the platform. To secure that in the beginning I proposed intranet implementation which is safer without much authentication required; however they think it will be once-for-all efforts if we can get a good implementation like OAuth into the platform as we start? (We are team of 6 and none of us know much about OAuth in fact!)
I don't know much about OAuth, so if it's worth to implement at the beginning of our system, I'll have to take a look and have my vote next week for OAuth in our meeting. This may effect how we gonna implement the whole web service thing, so may I ask anyone who's done large-scale web service /application before give some thoughts and advice for me?
Thanks.
OAuth 1 is nice if you want to use HTTP connections. If you can simply enforce HTTPS connections for all users, you might want to use OAuth 2, which is hardly more than a shared token between the client and server that's sent for each single request, plus a pre-defined way to get permission from the user via a web interface.
If you have to accept plain HTTP as well, OAuth 1 is really nice. It protects against replay attacks, packet injection or modification, uses a shared secret instead of shared token, etc. It is, however, a bit harder to implement than OAuth 2.
OAuth 2 is mostly about how to exchange username/password combinations for an access token, while OAuth 1 is mostly about how make semi-secure requests to a server over an unencrypted connection. If you don't need any of that, don't use OAuth. In many cases, Basic HTTP Authentication via HTTPS will do just fine.
OAuth is a standard for authentication and authorization. You can read about it in many places and learn; Generally the standard lets a client register in the authentication server, and then whenever this client attempts to access a protected resource, he is directed to the auth-server to get a token (first he gets a code, then he exchanges it with a token). But this is only generally, there are tons of details and options here...
Basically, one needs a good reason to use oAuth. If a simpler authentication mechanism is good for you - go for it.

Authentication for MVC4 Web Api

I'm trying to secure my MVC4 Web Api. Actually, I just really need an identity provider with some light security. My service is similar to twitter, from a security standpoint, there's not a lot of private data, but the service does need to know the userid for the caller.
It's also important to know that the web service will only be consumed by mobile devices right now, although a website may accompany it at some future point.
S.O. and the internet have led me to Thinktecture.IdentityModel, but man it seems complex and I can find exactly zero documentation or samples. I also haven't yet had a pleasant experience with claims-based authentication. I don't have a claims server, token provider, or anything like that, and it seems like you would need that to use this method. This all seems far to heavy for my situation.
I've also read about people implementing their own HMAC solution (https://github.com/cuongle/WebAPI.Hmac) or using OAuth (https://github.com/maksymilian-majer/DevDefined.OAuth) but these also seem a bit complex (I've read that OAuth without the helper class is enough to make the best developers cry, and I'm not the best). Janrain looks like it might work, but it looks like you have to pay for more than 2,500 authenticated users per year ...
What is the best way to implement a simple identity provider and security for Web Api?
Thanks!
I have attempted to answer a similar question to this before Create an OAuth 2.0 service provider using DotNetOpenAuth where I highlighted the Thinkecture Identity Server. The Setup instructions not too difficult (IMHO) The installation video is here and should help a lot.
I have updated my older answer with this too but there is also a fairly lightweight O-Auth 2.0 implementation example here Sample code here http://code.google.com/p/codesmith/downloads/detail?name=OAuth2.zip&can=2&q=#makechanges
Have you also read this well articulated question here Authenticating requests from mobile (iPhone) app to ASP.Net Web API (Feedback requested on my design)
Well, security is hard :)
As for Thinktecture.IdentityModel -- this is a token processing library (among other things) that you'd use in your WebAPI application. You'd use this so you don't need to do the logic to accept tokens (basic auth, SAML, SWT, JWT). Claims are just a side-effect.
If you're looking for an identity provider, then the sister open source project Thinktecture.IdentityServer is in beta for version 2. It's an identity provider that supports a custom database and issues tokens. The project URL is:
http://thinktecture.github.com/Thinktecture.IdentityServer.v2/
In response to the problem of finding example code as documentation, consider the samples folder in the Thinktecture github repo: https://github.com/thinktecture/Thinktecture.IdentityModel.45/tree/master/Samples
(Why do you need more reputation to comment on SO than to answer?)

Resources